aboutsummaryrefslogtreecommitdiffstats
path: root/lib/tools/doc
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/tools/doc
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/tools/doc')
-rw-r--r--lib/tools/doc/html/.gitignore0
-rw-r--r--lib/tools/doc/man3/.gitignore0
-rw-r--r--lib/tools/doc/pdf/.gitignore0
-rw-r--r--lib/tools/doc/src/Makefile132
-rw-r--r--lib/tools/doc/src/book.xml47
-rw-r--r--lib/tools/doc/src/cover.xml458
-rw-r--r--lib/tools/doc/src/cover_chapter.xml490
-rw-r--r--lib/tools/doc/src/cprof.xml294
-rw-r--r--lib/tools/doc/src/cprof_chapter.xml228
-rw-r--r--lib/tools/doc/src/eprof.xml150
-rw-r--r--lib/tools/doc/src/erlang_mode.xml324
-rw-r--r--lib/tools/doc/src/erlang_mode_chapter.xml251
-rw-r--r--lib/tools/doc/src/fascicules.xml18
-rw-r--r--lib/tools/doc/src/fprof.xml911
-rw-r--r--lib/tools/doc/src/fprof_chapter.xml141
-rw-r--r--lib/tools/doc/src/instrument.xml432
-rw-r--r--lib/tools/doc/src/make.dep33
-rw-r--r--lib/tools/doc/src/make.xml144
-rw-r--r--lib/tools/doc/src/note.gifbin0 -> 1539 bytes
-rw-r--r--lib/tools/doc/src/notes.xml475
-rw-r--r--lib/tools/doc/src/notes_history.xml243
-rw-r--r--lib/tools/doc/src/part.xml74
-rw-r--r--lib/tools/doc/src/part_notes.xml38
-rw-r--r--lib/tools/doc/src/part_notes_history.xml38
-rw-r--r--lib/tools/doc/src/ref_man.xml77
-rw-r--r--lib/tools/doc/src/tags.xml147
-rw-r--r--lib/tools/doc/src/venn1.fig63
-rw-r--r--lib/tools/doc/src/venn1.gifbin0 -> 3025 bytes
-rw-r--r--lib/tools/doc/src/venn1.ps205
-rw-r--r--lib/tools/doc/src/venn2.fig97
-rw-r--r--lib/tools/doc/src/venn2.gifbin0 -> 3369 bytes
-rw-r--r--lib/tools/doc/src/venn2.ps284
-rw-r--r--lib/tools/doc/src/warning.gifbin0 -> 1498 bytes
-rw-r--r--lib/tools/doc/src/xref.xml1554
-rw-r--r--lib/tools/doc/src/xref_chapter.xml383
35 files changed, 7731 insertions, 0 deletions
diff --git a/lib/tools/doc/html/.gitignore b/lib/tools/doc/html/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/tools/doc/html/.gitignore
diff --git a/lib/tools/doc/man3/.gitignore b/lib/tools/doc/man3/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/tools/doc/man3/.gitignore
diff --git a/lib/tools/doc/pdf/.gitignore b/lib/tools/doc/pdf/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/tools/doc/pdf/.gitignore
diff --git a/lib/tools/doc/src/Makefile b/lib/tools/doc/src/Makefile
new file mode 100644
index 0000000000..bab607c4bd
--- /dev/null
+++ b/lib/tools/doc/src/Makefile
@@ -0,0 +1,132 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../../vsn.mk
+VSN=$(TOOLS_VSN)
+APPLICATION=tools
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+XML_APPLICATION_FILES = ref_man.xml
+
+XML_REF3_FILES = \
+ cover.xml \
+ eprof.xml \
+ fprof.xml \
+ cprof.xml \
+ instrument.xml \
+ make.xml \
+ tags.xml \
+ xref.xml \
+ erlang_mode.xml
+
+XML_PART_FILES = part.xml part_notes.xml part_notes_history.xml
+
+XML_CHAPTER_FILES = \
+ cover_chapter.xml \
+ fprof_chapter.xml \
+ cprof_chapter.xml \
+ erlang_mode_chapter.xml \
+ xref_chapter.xml \
+ notes.xml \
+ notes_history.xml
+
+
+BOOK_FILES = book.xml
+
+XML_FILES = \
+ $(BOOK_FILES) $(XML_CHAPTER_FILES) \
+ $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_APPLICATION_FILES)
+
+GIF_FILES = \
+ venn1.gif \
+ venn2.gif
+
+# ----------------------------------------------------
+
+HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
+ $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
+
+INFO_FILE = ../../info
+
+MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3)
+
+HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
+
+TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+XML_FLAGS +=
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+$(HTMLDIR)/%.gif: %.gif
+ $(INSTALL_DATA) $< $@
+
+docs: pdf html man
+
+$(TOP_PDF_FILE): $(XML_FILES)
+
+pdf: $(TOP_PDF_FILE)
+
+html: gifs $(HTML_REF_MAN_FILE)
+
+man: $(MAN3_FILES)
+
+gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
+
+debug opt:
+
+clean clean_docs:
+ rm -rf $(HTMLDIR)/*
+ rm -f $(MAN3DIR)/*
+ rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f errs core *~
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_docs_spec: docs
+ $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf
+ $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf
+ $(INSTALL_DIR) $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(HTMLDIR)/* \
+ $(RELSYSDIR)/doc/html
+ $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man3
+ $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3
+
+release_spec:
+
diff --git a/lib/tools/doc/src/book.xml b/lib/tools/doc/src/book.xml
new file mode 100644
index 0000000000..96f6c426c3
--- /dev/null
+++ b/lib/tools/doc/src/book.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE book SYSTEM "book.dtd">
+
+<book xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header titlestyle="normal">
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Tools</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <insidecover>
+ </insidecover>
+ <pagetext>Tools</pagetext>
+ <preamble>
+ </preamble>
+ <parts lift="no">
+ <xi:include href="part.xml"/>
+ </parts>
+ <applications>
+ <xi:include href="ref_man.xml"/>
+ </applications>
+ <releasenotes>
+ <xi:include href="notes.xml"/>
+ </releasenotes>
+ <listofterms></listofterms>
+ <index></index>
+</book>
+
diff --git a/lib/tools/doc/src/cover.xml b/lib/tools/doc/src/cover.xml
new file mode 100644
index 0000000000..323bd0dda8
--- /dev/null
+++ b/lib/tools/doc/src/cover.xml
@@ -0,0 +1,458 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2001</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>cover</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <module>cover</module>
+ <modulesummary>A Coverage Analysis Tool for Erlang</modulesummary>
+ <description>
+ <p>The module <c>cover</c> provides a set of functions for coverage
+ analysis of Erlang programs, counting how many times each
+ <em>executable line</em> of code is executed when a program is run. <br></br>
+
+ An executable line contains an Erlang expression such as a matching
+ or a function call. A blank line or a line containing a comment,
+ function head or pattern in a <c>case</c>- or <c>receive</c> statement
+ is not executable.</p>
+ <p>Coverage analysis can be used to verify test cases, making sure all
+ relevant code is covered, and may also be helpful when looking for
+ bottlenecks in the code.</p>
+ <p>Before any analysis can take place, the involved modules must be
+ <em>Cover compiled</em>. This means that some extra information is
+ added to the module before it is compiled into a binary which then
+ is loaded. The source file of the module is not affected and no
+ <c>.beam</c> file is created.</p>
+ <p>Each time a function in a Cover compiled module is called,
+ information about the call is added to an internal database of Cover.
+ The coverage analysis is performed by examining the contents of
+ the Cover database. The output <c>Answer</c> is determined by two
+ parameters, <c>Level</c> and <c>Analysis</c>.</p>
+ <list type="bulleted">
+ <item>
+ <p><c>Level = module</c></p>
+ <p><c>Answer = {Module,Value}</c>, where <c>Module</c> is the module
+ name.</p>
+ </item>
+ <item>
+ <p><c>Level = function</c></p>
+ <p><c>Answer = [{Function,Value}]</c>, one tuple for each function in
+ the module. A function is specified by its module name <c>M</c>,
+ function name <c>F</c> and arity <c>A</c> as a tuple
+ <c>{M,F,A}</c>.</p>
+ </item>
+ <item>
+ <p><c>Level = clause</c></p>
+ <p><c>Answer = [{Clause,Value}]</c>, one tuple for each clause in
+ the module. A clause is specified by its module name <c>M</c>,
+ function name <c>F</c>, arity <c>A</c> and position in the function
+ definition <c>C</c> as a tuple <c>{M,F,A,C}</c>.</p>
+ </item>
+ <item>
+ <p><c>Level = line</c></p>
+ <p><c>Answer = [{Line,Value}]</c>, one tuple for each executable
+ line in the module. A line is specified by its module name <c>M</c>
+ and line number in the source file <c>N</c> as a tuple
+ <c>{M,N}</c>.</p>
+ </item>
+ <item>
+ <p><c>Analysis = coverage</c></p>
+ <p><c>Value = {Cov,NotCov}</c> where <c>Cov</c> is the number of
+ executable lines in the module, function, clause or line that have
+ been executed at least once and <c>NotCov</c> is the number of
+ executable lines that have not been executed.</p>
+ </item>
+ <item>
+ <p><c>Analysis = calls</c></p>
+ <p><c>Value = Calls</c> which is the number of times the module,
+ function, or clause has been called. In the case of line level
+ analysis, <c>Calls</c> is the number of times the line has been
+ executed.</p>
+ </item>
+ </list>
+ <p><em>Distribution</em></p>
+ <p>Cover can be used in a distributed Erlang system. One of the
+ nodes in the system must then be selected as the <em>main node</em>, and all Cover commands must be executed from this
+ node. The error reason <c>not_main_node</c> is returned if an
+ interface function is called on one of the remote nodes.</p>
+ <p>Use <c>cover:start/1</c> and <c>cover:stop/1</c> to add or
+ remove nodes. The same Cover compiled code will be loaded on each
+ node, and analysis will collect and sum up coverage data results
+ from all nodes.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>start() -> {ok,Pid} | {error,Reason}</name>
+ <fsummary>Start Cover.</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ <v>Reason = {already_started,Pid}</v>
+ </type>
+ <desc>
+ <p>Starts the Cover server which owns the Cover internal database.
+ This function is called automatically by the other functions in
+ the module.</p>
+ </desc>
+ </func>
+ <func>
+ <name>start(Nodes) -> {ok,StartedNodes} | {error,not_main_node}</name>
+ <fsummary>Start Cover on remote nodes.</fsummary>
+ <type>
+ <v>Nodes = StartedNodes = [atom()]</v>
+ </type>
+ <desc>
+ <p>Starts a Cover server on the each of given nodes, and loads
+ all cover compiled modules.</p>
+ </desc>
+ </func>
+ <func>
+ <name>compile(ModFile) -> Result</name>
+ <name>compile(ModFile, Options) -> Result</name>
+ <name>compile_module(ModFile) -> Result</name>
+ <name>compile_module(ModFile, Options) -> Result</name>
+ <fsummary>Compile a module for Cover analysis.</fsummary>
+ <type>
+ <v>ModFile = Module | File</v>
+ <v>&nbsp;Module = atom()</v>
+ <v>&nbsp;File = string()</v>
+ <v>Options = [Option]</v>
+ <v>&nbsp;Option = {i,Dir} | {d,Macro} | {d,Macro,Value}</v>
+ <d>See <c>compile:file/2.</c></d>
+ <v>Result = {ok,Module} | {error,File} | {error,not_main_node}</v>
+ </type>
+ <desc>
+ <p>Compiles a module for Cover analysis. The module is given by its
+ module name <c>Module</c> or by its file name <c>File</c>.
+ The <c>.erl</c> extension may be omitted. If the module is
+ located in another directory, the path has to be specified.</p>
+ <p><c>Options</c> is a list of compiler options which defaults to
+ <c>[]</c>. Only options defining include file directories and
+ macros are passed to <c>compile:file/2</c>, everything else is
+ ignored.</p>
+ <p>If the module is successfully Cover compiled, the function
+ returns <c>{ok,Module}</c>. Otherwise the function returns
+ <c>{error,File}</c>. Errors and warnings are printed as they
+ occur.</p>
+ <p>Note that the internal database is (re-)initiated during
+ the compilation, meaning any previously collected coverage data
+ for the module will be lost.</p>
+ </desc>
+ </func>
+ <func>
+ <name>compile_directory() -> [Result] | {error,Reason}</name>
+ <name>compile_directory(Dir) -> [Result] | {error,Reason}</name>
+ <name>compile_directory(Dir, Options) -> [Result] | {error,Reason}</name>
+ <fsummary>Compile all modules in a directory for Cover analysis.</fsummary>
+ <type>
+ <v>Dir = string()</v>
+ <v>Options = [Option]</v>
+ <d>See <c>compile_module/1,2</c></d>
+ <v>Result = {ok,Module} | {error,File} | {error,not_main_node}</v>
+ <d>See <c>compile_module/1,2</c></d>
+ <v>Reason = eacces | enoent</v>
+ </type>
+ <desc>
+ <p>Compiles all modules (<c>.erl</c> files) in a directory
+ <c>Dir</c> for Cover analysis the same way as
+ <c>compile_module/1,2</c> and returns a list with the return
+ values.</p>
+ <p><c>Dir</c> defaults to the current working directory.</p>
+ <p>The function returns <c>{error,eacces}</c> if the directory is not
+ readable or <c>{error,enoent}</c> if the directory does not exist.</p>
+ </desc>
+ </func>
+ <func>
+ <name>compile_beam(ModFile) -> Result</name>
+ <fsummary>Compile a module for Cover analysis, using an existing beam.</fsummary>
+ <type>
+ <v>ModFile = Module | BeamFile</v>
+ <v>&nbsp;Module = atom()</v>
+ <v>&nbsp;BeamFile = string()</v>
+ <v>Result = {ok,Module} | {error,BeamFile} | {error,Reason}</v>
+ <v>&nbsp;Reason = non_existing | {no_abstract_code,BeamFile} | {encrypted_abstract_code,BeamFile} | {already_cover_compiled,no_beam_found,Module} | not_main_node</v>
+ </type>
+ <desc>
+ <p>Does the same as <c>compile/1,2</c>, but uses an existing
+ <c>.beam</c> file as base, i.e. the module is not compiled
+ from source. Thus <c>compile_beam/1</c> is faster than
+ <c>compile/1,2</c>.</p>
+ <p>Note that the existing <c>.beam</c> file must contain
+ <em>abstract code</em>, i.e. it must have been compiled with
+ the <c>debug_info</c> option. If not, the error reason
+ <c>{no_abstract_code,BeamFile}</c> is returned.
+ If the abstract code is encrypted, and no key is available
+ for decrypting it, the error reason
+ <c><![CDATA[{encrypted_abstract_code,BeamFile} is returned. <p>If only the module name (i.e. not the full name of the <c>.beam]]></c> file) is given to this function, the
+ <c>.beam</c> file is found by calling
+ <c>code:which(Module)</c>. If no <c>.beam</c> file is found,
+ the error reason <c>non_existing</c> is returned. If the
+ module is already cover compiled with <c>compile_beam/1</c>,
+ the <c>.beam</c> file will be picked from the same location
+ as the first time it was compiled. If the module is already
+ cover compiled with <c>compile/1,2</c>, there is no way to
+ find the correct <c>.beam</c> file, so the error reason
+ <c>{already_cover_compiled,no_beam_found,Module}</c> is
+ returned.</p>
+ <p><c>{error,BeamFile}</c> is returned if the compiled code
+ can not be loaded on the node.</p>
+ </desc>
+ </func>
+ <func>
+ <name>compile_beam_directory() -> [Result] | {error,Reason}</name>
+ <name>compile_beam_directory(Dir) -> [Result] | {error,Reason}</name>
+ <fsummary>Compile all .beam files in a directory for Cover analysis.</fsummary>
+ <type>
+ <v>Dir = string()</v>
+ <v>Result = See compile_beam/1</v>
+ <v>Reason = eacces | enoent</v>
+ </type>
+ <desc>
+ <p>Compiles all modules (<c>.beam</c> files) in a directory
+ <c>Dir</c> for Cover analysis the same way as
+ <c>compile_beam/1</c> and returns a list with the return
+ values.</p>
+ <p><c>Dir</c> defaults to the current working directory.</p>
+ <p>The function returns <c>{error,eacces}</c> if the directory is not
+ readable or <c>{error,enoent}</c> if the directory does not exist.</p>
+ </desc>
+ </func>
+ <func>
+ <name>analyse(Module) -> {ok,Answer} | {error,Error}</name>
+ <name>analyse(Module, Analysis) -> {ok,Answer} | {error,Error}</name>
+ <name>analyse(Module, Level) -> {ok,Answer} | {error,Error}</name>
+ <name>analyse(Module, Analysis, Level) -> {ok,Answer} | {error,Error}</name>
+ <fsummary>Analyse a Cover compiled module.</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ <v>Analysis = coverage | calls</v>
+ <v>Level = line | clause | function | module</v>
+ <v>Answer = {Module,Value} | [{Item,Value}]</v>
+ <v>&nbsp;Item = Line | Clause | Function</v>
+ <v>&nbsp;&nbsp;Line = {M,N}</v>
+ <v>&nbsp;&nbsp;Clause = {M,F,A,C}</v>
+ <v>&nbsp;&nbsp;Function = {M,F,A}</v>
+ <v>&nbsp;&nbsp;&nbsp;M = F = atom()</v>
+ <v>&nbsp;&nbsp;&nbsp;N = A = C = integer()</v>
+ <v>&nbsp;Value = {Cov,NotCov} | Calls</v>
+ <v>&nbsp;&nbsp;Cov = NotCov = Calls = integer()</v>
+ <v>Error = {not_cover_compiled,Module} | not_main_node</v>
+ </type>
+ <desc>
+ <p>Performs analysis of a Cover compiled module <c>Module</c>, as
+ specified by <c>Analysis</c> and <c>Level</c> (see above), by
+ examining the contents of the internal database.</p>
+ <p><c>Analysis</c> defaults to <c>coverage</c> and <c>Level</c>
+ defaults to <c>function</c>.</p>
+ <p>If <c>Module</c> is not Cover compiled, the function returns
+ <c>{error,{not_cover_compiled,Module}}</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>analyse_to_file(Module) -> </name>
+ <name>analyse_to_file(Module,Options) -> </name>
+ <name>analyse_to_file(Module, OutFile) -> </name>
+ <name>analyse_to_file(Module, OutFile, Options) -> {ok,OutFile} | {error,Error}</name>
+ <fsummary>Detailed coverage analysis of a Cover compiled module.</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ <v>OutFile = string()</v>
+ <v>Options = [Option]</v>
+ <v>Option = html</v>
+ <v>Error = {not_cover_compiled,Module} | {file,File,Reason} | no_source_code_found | not_main_node</v>
+ <v>&nbsp;File = string()</v>
+ <v>&nbsp;Reason = term()</v>
+ </type>
+ <desc>
+ <p>Makes a copy <c>OutFile</c> of the source file for a module
+ <c>Module</c>, where it for each executable line is specified
+ how many times it has been executed.</p>
+ <p>The output file <c>OutFile</c> defaults to
+ <c>Module.COVER.out</c>, or <c>Module.COVER.html</c> if the
+ option <c>html</c> was used.</p>
+ <p>If <c>Module</c> is not Cover compiled, the function returns
+ <c>{error,{not_cover_compiled,Module}}</c>.</p>
+ <p>If the source file and/or the output file cannot be opened using
+ <c>file:open/2</c>, the function returns
+ <c>{error,{file,File,Reason}}</c> where <c>File</c> is the file
+ name and <c>Reason</c> is the error reason.</p>
+ <p>If the module was cover compiled from the <c>.beam</c>
+ file, i.e. using <c>compile_beam/1</c> or
+ <c>compile_beam_directory/0,1</c>, it is assumed that the
+ source code can be found in the same directory as the
+ <c>.beam</c> file, or in <c>../src</c> relative to that
+ directory. If no source code is found,
+ <c>,{error,no_source_code_found}</c> is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>modules() -> [Module] | {error,not_main_node}</name>
+ <fsummary>Return all Cover compiled modules.</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ </type>
+ <desc>
+ <p>Returns a list with all modules that are currently Cover
+ compiled.</p>
+ </desc>
+ </func>
+ <func>
+ <name>imported_modules() -> [Module] | {error,not_main_node}</name>
+ <fsummary>Return all modules for which there are imported data.</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ </type>
+ <desc>
+ <p>Returns a list with all modules for which there are
+ imported data.</p>
+ </desc>
+ </func>
+ <func>
+ <name>imported() -> [File] | {error,not_main_node}</name>
+ <fsummary>Return all imported files.</fsummary>
+ <type>
+ <v>File = string()</v>
+ </type>
+ <desc>
+ <p>Returns a list with all imported files.</p>
+ </desc>
+ </func>
+ <func>
+ <name>which_nodes() -> [Node] | {error,not_main_node}</name>
+ <fsummary>Return all nodes that are part of the coverage analysis.</fsummary>
+ <type>
+ <v>Node = atom()</v>
+ </type>
+ <desc>
+ <p>Returns a list with all nodes that are part of the coverage
+ analysis. Note that the current node is not returned. This
+ node is always part of the analysis.</p>
+ </desc>
+ </func>
+ <func>
+ <name>is_compiled(Module) -> {file,File} | false | {error,not_main_node}</name>
+ <fsummary>Check if a module is Cover compiled.</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ <v>Beam = string()</v>
+ </type>
+ <desc>
+ <p>Returns <c>{file,File}</c> if the module <c>Module</c> is
+ Cover compiled, or <c>false</c> otherwise. <c>File</c> is
+ the <c>.erl</c> file used by <c>cover:compile_module/1,2</c>
+ or the <c>.beam</c> file used by <c>compile_beam/1</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>reset(Module) -></name>
+ <name>reset() -> ok | {error,not_main_node}</name>
+ <fsummary>Reset coverage data for Cover compiled modules.</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ </type>
+ <desc>
+ <p>Resets all coverage data for a Cover compiled module
+ <c>Module</c> in the Cover database on all nodes. If the
+ argument is omitted, the coverage data will be reset for all
+ modules known by Cover.</p>
+ <p>If <c>Module</c> is not Cover compiled, the function returns
+ <c>{error,{not_cover_compiled,Module}}</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>export(ExportFile)</name>
+ <name>export(ExportFile,Module) -> ok | {error,Reason}</name>
+ <fsummary>Reset coverage data for Cover compiled modules.</fsummary>
+ <type>
+ <v>ExportFile = string()</v>
+ <v>Module = atom()</v>
+ <v>Reason = {not_cover_compiled,Module} | {cant_open_file,ExportFile,Reason} | not_main_node</v>
+ </type>
+ <desc>
+ <p>Exports the current coverage data for <c>Module</c> to the
+ file <c>ExportFile</c>. It is recommended to name the
+ <c>ExportFile</c> with the extension <c>.coverdata</c>, since
+ other filenames can not be read by the web based interface to
+ cover.</p>
+ <p>If <c>Module</c> is not given, data for all Cover compiled
+ or earlier imported modules is exported.</p>
+ <p>This function is useful if coverage data from different
+ systems is to be merged.</p>
+ <p>See also <c>cover:import/1</c></p>
+ </desc>
+ </func>
+ <func>
+ <name>import(ExportFile) -> ok | {error,Reason}</name>
+ <fsummary>Reset coverage data for Cover compiled modules.</fsummary>
+ <type>
+ <v>ExportFile = string()</v>
+ <v>Reason = {cant_open_file,ExportFile,Reason} | not_main_node</v>
+ </type>
+ <desc>
+ <p>Imports coverage data from the file <c>ExportFile</c>
+ created with <c>cover:export/1,2</c>. Any analysis performed
+ after this will include the imported data.</p>
+ <p>Note that when compiling a module <em>all existing coverage data is removed</em>, including imported data. If a module is
+ already compiled when data is imported, the imported data is
+ <em>added</em> to the existing coverage data.</p>
+ <p>Coverage data from several export files can be imported
+ into one system. The coverage data is then added up when
+ analysing.</p>
+ <p>Coverage data for a module can not be imported from the
+ same file twice unless the module is first reset or
+ compiled. The check is based on the filename, so you can
+ easily fool the system by renaming your export file.</p>
+ <p>See also <c>cover:export/1,2</c></p>
+ </desc>
+ </func>
+ <func>
+ <name>stop() -> ok | {error,not_main_node}</name>
+ <fsummary>Stop Cover.</fsummary>
+ <desc>
+ <p>Stops the Cover server and unloads all Cover compiled code.</p>
+ </desc>
+ </func>
+ <func>
+ <name>stop(Nodes) -> ok | {error,not_main_node}</name>
+ <fsummary>Stop Cover on remote nodes.</fsummary>
+ <type>
+ <v>Nodes = [atom()]</v>
+ </type>
+ <desc>
+ <p>Stops the Cover server and unloads all Cover compiled code
+ on the given nodes. Data stored in the Cover database on the
+ remote nodes is fetched and stored on the main node.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>SEE ALSO</title>
+ <p>code(3), compile(3)</p>
+ </section>
+</erlref>
+
diff --git a/lib/tools/doc/src/cover_chapter.xml b/lib/tools/doc/src/cover_chapter.xml
new file mode 100644
index 0000000000..b4f7919183
--- /dev/null
+++ b/lib/tools/doc/src/cover_chapter.xml
@@ -0,0 +1,490 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2001</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>cover</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>cover_chapter.xml</file>
+ </header>
+
+ <section>
+ <title>Introduction</title>
+ <p>The module <c>cover</c> provides a set of functions for coverage
+ analysis of Erlang programs, counting how many times each
+ <seealso marker="#lines">executable line</seealso> is executed.</p>
+ <p>Coverage analysis can be used to verify test cases, making sure all
+ relevant code is covered, and may be helpful when looking for
+ bottlenecks in the code.</p>
+ </section>
+
+ <section>
+ <title>Getting Started With Cover</title>
+
+ <section>
+ <title>Example</title>
+ <p>Assume that a test case for the following program should be
+ verified:</p>
+ <code type="none">
+-module(channel).
+-behaviour(gen_server).
+
+-export([start_link/0,stop/0]).
+-export([alloc/0,free/1]). % client interface
+-export([init/1,handle_call/3,terminate/2]). % callback functions
+
+start_link() ->
+ gen_server:start_link({local,channel},channel,[],[]).
+
+stop() ->
+ gen_server:call(channel,stop).
+
+%%%-Client interface functions-------------------------------------------
+
+alloc() ->
+ gen_server:call(channel,alloc).
+
+free(Channel) ->
+ gen_server:call(channel,{free,Channel}).
+
+%%%-gen_server callback functions----------------------------------------
+
+init(_Arg) ->
+ {ok,channels()}.
+
+handle_call(stop,Client,Channels) ->
+ {stop,normal,ok,Channels};
+
+handle_call(alloc,Client,Channels) ->
+ {Ch,Channels2} = alloc(Channels),
+ {reply,{ok,Ch},Channels2};
+
+handle_call({free,Channel},Client,Channels) ->
+ Channels2 = free(Channel,Channels),
+ {reply,ok,Channels2}.
+
+terminate(_Reason,Channels) ->
+ ok.
+
+%%%-Internal functions---------------------------------------------------
+
+channels() ->
+ [ch1,ch2,ch3].
+
+alloc([Channel|Channels]) ->
+ {Channel,Channels};
+alloc([]) ->
+ false.
+
+free(Channel,Channels) ->
+ [Channel|Channels].</code>
+ <p>The test case is implemented as follows:</p>
+ <code type="none">
+-module(test).
+-export([s/0]).
+
+s() ->
+ {ok,Pid} = channel:start_link(),
+ {ok,Ch1} = channel:alloc(),
+ ok = channel:free(Ch1),
+ ok = channel:stop().</code>
+ </section>
+
+ <section>
+ <title>Preparation</title>
+ <p>First of all, Cover must be started. This spawns a process which
+ owns the Cover database where all coverage data will be stored.</p>
+ <pre>
+1> <input>cover:start().</input>
+{ok,&lt;0.30.0>}</pre>
+ <p>To include other nodes in the coverage analysis, use
+ <c>start/1</c>. All cover compiled modules will then be loaded
+ on all nodes, and data from all nodes will be summed up when
+ analysing. For simplicity this example only involves the
+ current node.</p>
+ <p>Before any analysis can take place, the involved modules must be
+ <em>Cover compiled</em>. This means that some extra information is
+ added to the module before it is compiled into a binary which then
+ is <seealso marker="#loading">loaded</seealso>. The source file of
+ the module is not affected and no <c>.beam</c> file is created.</p>
+ <pre>
+2> <input>cover:compile_module(channel).</input>
+{ok,channel}</pre>
+ <p>Each time a function in the Cover compiled module <c>channel</c>
+ is called, information about the call will be added to the Cover
+ database. Run the test case:</p>
+ <pre>
+3> <input>test:s().</input>
+ok</pre>
+ <p>Cover analysis is performed by examining the contents of the Cover
+ database. The output is determined by two parameters, <c>Level</c>
+ and <c>Analysis</c>. <c>Analysis</c> is either <c>coverage</c> or
+ <c>calls</c> and determines the type of the analysis. <c>Level</c>
+ is either <c>module</c>, <c>function</c>, <c>clause</c>, or
+ <c>line</c> and determines the level of the analysis.</p>
+ </section>
+
+ <section>
+ <title>Coverage Analysis</title>
+ <p>Analysis of type <c>coverage</c> is used to find out how much of
+ the code has been executed and how much has not been executed.
+ Coverage is represented by a tuple <c>{Cov,NotCov}</c>, where
+ <c>Cov</c> is the number of executable lines that have been executed
+ at least once and <c>NotCov</c> is the number of executable lines
+ that have not been executed.</p>
+ <p>If the analysis is made on module level, the result is given for
+ the entire module as a tuple <c>{Module,{Cov,NotCov}}</c>:</p>
+ <pre>
+4> <input>cover:analyse(channel,coverage,module).</input>
+{ok,{channel,{14,1}}}</pre>
+ <p>For <c>channel</c>, the result shows that 14 lines in the module
+ are covered but one line is not covered.</p>
+ <p>If the analysis is made on function level, the result is given as
+ a list of tuples <c>{Function,{Cov,NotCov}}</c>, one for each
+ function in the module. A function is specified by its module name,
+ function name and arity:</p>
+ <pre>
+5> <input>cover:analyse(channel,coverage,function).</input>
+{ok,[{{channel,start_link,0},{1,0}},
+ {{channel,stop,0},{1,0}},
+ {{channel,alloc,0},{1,0}},
+ {{channel,free,1},{1,0}},
+ {{channel,init,1},{1,0}},
+ {{channel,handle_call,3},{5,0}},
+ {{channel,terminate,2},{1,0}},
+ {{channel,channels,0},{1,0}},
+ {{channel,alloc,1},{1,1}},
+ {{channel,free,2},{1,0}}]}</pre>
+ <p>For <c>channel</c>, the result shows that the uncovered line is in
+ the function <c>channel:alloc/1</c>.</p>
+ <p>If the analysis is made on clause level, the result is given as
+ a list of tuples <c>{Clause,{Cov,NotCov}}</c>, one for each
+ function clause in the module. A clause is specified by its module
+ name, function name, arity and position within the function
+ definition:</p>
+ <pre>
+6> <input>cover:analyse(channel,coverage,clause).</input>
+{ok,[{{channel,start_link,0,1},{1,0}},
+ {{channel,stop,0,1},{1,0}},
+ {{channel,alloc,0,1},{1,0}},
+ {{channel,free,1,1},{1,0}},
+ {{channel,init,1,1},{1,0}},
+ {{channel,handle_call,3,1},{1,0}},
+ {{channel,handle_call,3,2},{2,0}},
+ {{channel,handle_call,3,3},{2,0}},
+ {{channel,terminate,2,1},{1,0}},
+ {{channel,channels,0,1},{1,0}},
+ {{channel,alloc,1,1},{1,0}},
+ {{channel,alloc,1,2},{0,1}},
+ {{channel,free,2,1},{1,0}}]}</pre>
+ <p>For <c>channel</c>, the result shows that the uncovered line is in
+ the second clause of <c>channel:alloc/1</c>.</p>
+ <p>Finally, if the analysis is made on line level, the result is given
+ as a list of tuples <c>{Line,{Cov,NotCov}}</c>, one for each
+ executable line in the source code. A line is specified by its
+ module name and line number.</p>
+ <pre>
+7> <input>cover:analyse(channel,coverage,line).</input>
+{ok,[{{channel,9},{1,0}},
+ {{channel,12},{1,0}},
+ {{channel,17},{1,0}},
+ {{channel,20},{1,0}},
+ {{channel,25},{1,0}},
+ {{channel,28},{1,0}},
+ {{channel,31},{1,0}},
+ {{channel,32},{1,0}},
+ {{channel,35},{1,0}},
+ {{channel,36},{1,0}},
+ {{channel,39},{1,0}},
+ {{channel,44},{1,0}},
+ {{channel,47},{1,0}},
+ {{channel,49},{0,1}},
+ {{channel,52},{1,0}}]}</pre>
+ <p>For <c>channel</c>, the result shows that the uncovered line is
+ line number 49.</p>
+ </section>
+
+ <section>
+ <title>Call Statistics</title>
+ <p>Analysis of type <c>calls</c> is used to find out how many times
+ something has been called and is represented by an integer
+ <c>Calls</c>.</p>
+ <p>If the analysis is made on module level, the result is given as a
+ tuple <c>{Module,Calls}</c>. Here <c>Calls</c> is the total number
+ of calls to functions in the module:</p>
+ <pre>
+8> <input>cover:analyse(channel,calls,module).</input>
+{ok,{channel,12}}</pre>
+ <p>For <c>channel</c>, the result shows that a total of twelve calls
+ have been made to functions in the module.</p>
+ <p>If the analysis is made on function level, the result is given as
+ a list of tuples <c>{Function,Calls}</c>. Here <c>Calls</c> is
+ the number of calls to each function:</p>
+ <pre>
+9> <input>cover:analyse(channel,calls,function).</input>
+{ok,[{{channel,start_link,0},1},
+ {{channel,stop,0},1},
+ {{channel,alloc,0},1},
+ {{channel,free,1},1},
+ {{channel,init,1},1},
+ {{channel,handle_call,3},3},
+ {{channel,terminate,2},1},
+ {{channel,channels,0},1},
+ {{channel,alloc,1},1},
+ {{channel,free,2},1}]}</pre>
+ <p>For <c>channel</c>, the result shows that <c>handle_call/3</c> is
+ the most called function in the module (three calls). All other
+ functions have been called once.</p>
+ <p>If the analysis is made on clause level, the result is given as
+ a list of tuples <c>{Clause,Calls}</c>. Here <c>Calls</c> is
+ the number of calls to each function clause:</p>
+ <pre>
+10> <input>cover:analyse(channel,calls,clause).</input>
+{ok,[{{channel,start_link,0,1},1},
+ {{channel,stop,0,1},1},
+ {{channel,alloc,0,1},1},
+ {{channel,free,1,1},1},
+ {{channel,init,1,1},1},
+ {{channel,handle_call,3,1},1},
+ {{channel,handle_call,3,2},1},
+ {{channel,handle_call,3,3},1},
+ {{channel,terminate,2,1},1},
+ {{channel,channels,0,1},1},
+ {{channel,alloc,1,1},1},
+ {{channel,alloc,1,2},0},
+ {{channel,free,2,1},1}]}</pre>
+ <p>For <c>channel</c>, the result shows that all clauses have been
+ called once, except the second clause of <c>channel:alloc/1</c>
+ which has not been called at all.</p>
+ <p>Finally, if the analysis is made on line level, the result is given
+ as a list of tuples <c>{Line,Calls}</c>. Here <c>Calls</c> is
+ the number of times each line has been executed:</p>
+ <pre>
+11> <input>cover:analyse(channel,calls,line).</input>
+{ok,[{{channel,9},1},
+ {{channel,12},1},
+ {{channel,17},1},
+ {{channel,20},1},
+ {{channel,25},1},
+ {{channel,28},1},
+ {{channel,31},1},
+ {{channel,32},1},
+ {{channel,35},1},
+ {{channel,36},1},
+ {{channel,39},1},
+ {{channel,44},1},
+ {{channel,47},1},
+ {{channel,49},0},
+ {{channel,52},1}]}</pre>
+ <p>For <c>channel</c>, the result shows that all lines have been
+ executed once, except line number 49 which has not been executed at
+ all.</p>
+ </section>
+
+ <section>
+ <title>Analysis to File</title>
+ <p>A line level calls analysis of <c>channel</c> can be written to
+ a file using <c>cover:analysis_to_file/1</c>:</p>
+ <pre>
+12> <input>cover:analyse_to_file(channel).</input>
+{ok,"channel.COVER.out"}</pre>
+ <p>The function creates a copy of <c>channel.erl</c> where it for
+ each executable line is specified how many times that line has been
+ executed. The output file is called <c>channel.COVER.out</c>.</p>
+ <pre>
+File generated from channel.erl by COVER 2001-05-21 at 11:16:38
+
+****************************************************************************
+
+ | -module(channel).
+ | -behaviour(gen_server).
+ |
+ | -export([start_link/0,stop/0]).
+ | -export([alloc/0,free/1]). % client interface
+ | -export([init/1,handle_call/3,terminate/2]). % callback functions
+ |
+ | start_link() ->
+ 1..| gen_server:start_link({local,channel},channel,[],[]).
+ |
+ | stop() ->
+ 1..| gen_server:call(channel,stop).
+ |
+ | %%%-Client interface functions------------------------------------
+ |
+ | alloc() ->
+ 1..| gen_server:call(channel,alloc).
+ |
+ | free(Channel) ->
+ 1..| gen_server:call(channel,{free,Channel}).
+ |
+ | %%%-gen_server callback functions---------------------------------
+ |
+ | init(_Arg) ->
+ 1..| {ok,channels()}.
+ |
+ | handle_call(stop,Client,Channels) ->
+ 1..| {stop,normal,ok,Channels};
+ |
+ | handle_call(alloc,Client,Channels) ->
+ 1..| {Ch,Channels2} = alloc(Channels),
+ 1..| {reply,{ok,Ch},Channels2};
+ |
+ | handle_call({free,Channel},Client,Channels) ->
+ 1..| Channels2 = free(Channel,Channels),
+ 1..| {reply,ok,Channels2}.
+ |
+ | terminate(_Reason,Channels) ->
+ 1..| ok.
+ |
+ | %%%-Internal functions--------------------------------------------
+ |
+ | channels() ->
+ 1..| [ch1,ch2,ch3].
+ |
+ | alloc([Channel|Channels]) ->
+ 1..| {Channel,Channels};
+ | alloc([]) ->
+ 0..| false.
+ |
+ | free(Channel,Channels) ->
+ 1..| [Channel|Channels].</pre>
+ </section>
+
+ <section>
+ <title>Conclusion</title>
+ <p>By looking at the results from the analyses, it can be deducted
+ that the test case does not cover the case when all channels are
+ allocated and <c>test.erl</c> should be extended accordingly. <br></br>
+
+ Incidentally, when the test case is corrected a bug in <c>channel</c>
+ should indeed be discovered.</p>
+ <p>When the Cover analysis is ready, Cover is stopped and all Cover
+ compiled modules are <seealso marker="#loading">unloaded</seealso>.
+ The code for <c>channel</c> is now loaded as usual from a
+ <c>.beam</c> file in the current path.</p>
+ <pre>
+13> <input>code:which(channel).</input>
+cover_compiled
+14> <input>cover:stop().</input>
+ok
+15> <input>code:which(channel).</input>
+"./channel.beam"</pre>
+ </section>
+ </section>
+
+ <section>
+ <title>Miscellaneous</title>
+
+ <section>
+ <title>Performance</title>
+ <p>Execution of code in Cover compiled modules is slower and more
+ memory consuming than for regularly compiled modules. As the Cover
+ database contains information about each executable line in each
+ Cover compiled module, performance decreases proportionally to
+ the size and number of the Cover compiled modules.</p>
+ </section>
+
+ <section>
+ <marker id="lines"></marker>
+ <title>Executable Lines</title>
+ <p>Cover uses the concept of <em>executable lines</em>, which is lines
+ of code containing an executable expression such as a matching or
+ a function call. A blank line or a line containing a comment,
+ function head or pattern in a <c>case</c>- or <c>receive</c>
+ statement is not executable.</p>
+ <p>In the example below, lines number 2,4,6,8 and 11 are executable
+ lines:</p>
+ <p></p>
+ <pre>
+1: is_loaded(Module,Compiled) ->
+2: case get_file(Module,Compiled) of
+3: {ok,File} ->
+4: case code:which(Module) of
+5: ?TAG ->
+6: {loaded,File};
+7: _ ->
+8: unloaded
+9: end;
+10: false ->
+11: false
+12: end.</pre>
+ </section>
+
+ <section>
+ <marker id="loading"></marker>
+ <title>Code Loading Mechanism</title>
+ <p>When a module is Cover compiled, it is also loaded using the normal
+ code loading mechanism of Erlang. This means that if a Cover
+ compiled module is re-loaded during a Cover session, for example
+ using <c>c(Module)</c>, it will no longer be Cover compiled.</p>
+ <p>Use <c>cover:is_compiled/1</c> or <c>code:which/1</c> to see if
+ a module is Cover compiled (and still loaded) or not.</p>
+ <p>When Cover is stopped, all Cover compiled modules are unloaded.</p>
+ </section>
+ </section>
+
+ <section>
+ <title>Using the Web Based User Interface to Cover</title>
+
+ <section>
+ <title>Introduction</title>
+ <p>To ease the use of Cover there is a web based user interface
+ to Cover called WebCover. WebCover is designed to be started
+ and used via WebTool. It is possible to Cover compile Erlang
+ modules and to generate printable Cover and Call analyses via
+ the web based user interface.</p>
+ </section>
+
+ <section>
+ <title>Start the Web Based User Interface to Cover</title>
+ <p>To start WebCover you can either start WebTool, point a
+ browser to the start page of WebTool and start WebCover from
+ there, or you can use the <c>start_webtool</c> script to start
+ Webtool, WebCover and a browser. See WebTool documentation for
+ further information.</p>
+ <p>Currently WebCover is only compatible
+ with Internet Explorer and Netscape Navigator 4.0 and higher.</p>
+ </section>
+
+ <section>
+ <title>Navigating WebCover</title>
+ <p>From the menu in the lefthand frame you can select the
+ <c>Nodes</c>, <c>Compile</c>, <c>Import</c> or <c>Result</c>
+ page.</p>
+ <p>From the <c>Nodes</c> page you can add remote nodes to
+ participate in the coverage analysis. Coverage data from all
+ involved nodes will then be merged during analysis.</p>
+ <p>From the <c>Compile</c> page you can Cover compile <c>.erl</c>
+ or <c>.beam</c> files.</p>
+ <p>From the <c>Import</c> page you can import coverage data from
+ a previous analysis. Imported data will then be merged with
+ the current coverage data. <em>Note</em> that it is only possible to
+ import files with the extension <c>.coverdata</c>.</p>
+ <p>From the <c>Result</c> page you can analyse, reset or export
+ coverage data.</p>
+ <p>Please follow the instructions on each page.</p>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/tools/doc/src/cprof.xml b/lib/tools/doc/src/cprof.xml
new file mode 100644
index 0000000000..421ed7875a
--- /dev/null
+++ b/lib/tools/doc/src/cprof.xml
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2002</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>cprof</title>
+ <prepared>Raimo Niskanen</prepared>
+ <responsible>nobody</responsible>
+ <docno></docno>
+ <approved>nobody</approved>
+ <checked></checked>
+ <date>2002-09-12</date>
+ <rev>PA1</rev>
+ <file>cprof.sgml</file>
+ </header>
+ <module>cprof</module>
+ <modulesummary>A simple Call Count Profiling Tool using breakpoints for minimal runtime performance impact.</modulesummary>
+ <description>
+ <p>The <c>cprof</c> module is used to profile a program
+ to find out how many times different functions are called.
+ Breakpoints similar to local call trace, but containing a
+ counter, are used to minimise runtime performance impact.
+ </p>
+ <p>Since breakpoints are used there is no need for special
+ compilation of any module to be profiled. For now these
+ breakpoints can only be set on BEAM code so <term id="BIF"></term>s
+ cannot be call count traced.
+ </p>
+ <p>The size of the call counters is the host machine word
+ size. One bit is used when pausing the counter, so the maximum
+ counter value for a 32-bit host is 2147483647.
+ </p>
+ <p>The profiling result is delivered as a term containing a
+ sorted list of entries, one per module. Each module entry
+ contains a sorted list of functions. The sorting order in both
+ cases is of decreasing call count.
+ </p>
+ <p>Call count tracing is very lightweight compared to other forms
+ of tracing since no trace message has to be generated. Some
+ measurements indicates performance degradation in the vicinity
+ of 10 percent.
+ <marker id="analyse"></marker>
+</p>
+ </description>
+ <funcs>
+ <func>
+ <name>analyse() -> {AllCallCount, ModAnalysisList}</name>
+ <name>analyse(Limit) -> {AllCallCount, ModAnalysisList}</name>
+ <name>analyse(Mod) -> ModAnlysis</name>
+ <name>analyse(Mod, Limit) -> ModAnalysis</name>
+ <fsummary>Collect and analyse call counters.</fsummary>
+ <type>
+ <v>Limit = integer()</v>
+ <v>Mod = atom()</v>
+ <v>AllCallCount = integer()</v>
+ <v>ModAnalysisList = [ModAnalysis]</v>
+ <v>ModAnalysis = {Mod, ModCallCount, FuncAnalysisList}</v>
+ <v>ModCallCount = integer()</v>
+ <v>FuncAnalysisList = [{{Mod, Func, Arity}, FuncCallCount}]</v>
+ <v>Func = atom()</v>
+ <v>Arity = integer()</v>
+ <v>FuncCallCount = integer()</v>
+ </type>
+ <desc>
+ <p>Collects and analyses the call counters presently in the
+ node for either module <c>Mod</c>, or for all modules
+ (except <c>cprof</c> itself), and returns: </p>
+ <taglist>
+ <tag><c>FuncAnalysisList</c></tag>
+ <item>A list of tuples, one for each function in a module, in
+ decreasing <c>FuncCallCount</c> order.</item>
+ <tag><c>ModCallCount</c></tag>
+ <item>The sum of <c>FuncCallCount</c> values for all
+ functions in module <c>Mod</c>.</item>
+ <tag><c>AllCallCount</c></tag>
+ <item>The sum of <c>ModCallCount</c> values for all modules
+ concerned in <c>ModAnalysisList</c>.</item>
+ <tag><c>ModAnalysisList</c></tag>
+ <item>A list of tuples, one for each module except
+ <c>cprof</c>, in decreasing <c>ModCallCount</c> order.</item>
+ </taglist>
+ <p>If call counters are still running while
+ <c>analyse/0..2</c> is executing, you might get an
+ inconsistent result. This happens if the process executing
+ <c>analyse/0..2</c> gets scheduled out so some other process
+ can increment the counters that are being analysed, Calling
+ <c>pause()</c> before analysing takes care of the problem.
+ </p>
+ <p>If the <c>Mod</c> argument is given, the result contains a
+ <c>ModAnalysis</c> tuple for module <c>Mod</c> only,
+ otherwise the result contains one <c>ModAnalysis</c> tuple
+ for all modules returned from <c>code:all_loaded()</c>
+ except <c>cprof</c> itself.
+ </p>
+ <p>All functions with a <c>FuncCallCount</c> lower than
+ <c>Limit</c> are excluded from <c>FuncAnalysisList</c>. They
+ are still included in <c>ModCallCount</c>, though.
+ The default value for <c>Limit</c> is <c>1</c>.
+ <marker id="pause_0"></marker>
+</p>
+ </desc>
+ </func>
+ <func>
+ <name>pause() -> integer()</name>
+ <fsummary>Pause running call count trace for all functions.</fsummary>
+ <desc>
+ <p>Pause call count tracing for all functions in all modules
+ and stop it for all functions in modules to be
+ loaded. This is the same as
+ <c>(pause({'_','_','_'})+stop({on_load}))</c>.
+ </p>
+ <p>See also
+ <seealso marker="#pause">pause/1..3</seealso> below.
+ <marker id="pause"></marker>
+</p>
+ </desc>
+ </func>
+ <func>
+ <name>pause(FuncSpec) -> integer()</name>
+ <name>pause(Mod, Func) -> integer()</name>
+ <name>pause(Mod, Func, Arity) -> integer()</name>
+ <fsummary>Pause running call count trace for matching functions.</fsummary>
+ <type>
+ <v>FuncSpec = Mod | {Mod,Func,Arity}, {FS}</v>
+ <v>Mod = atom()</v>
+ <v>Func = atom()</v>
+ <v>Arity = integer()</v>
+ <v>FS = term()</v>
+ </type>
+ <desc>
+ <p>Pause call counters for matching functions in matching
+ modules. The <c>FS</c> argument can be used to
+ specify the first argument to
+ <c>erlang:trace_pattern/3</c>. See erlang(3).
+ </p>
+ <p>The call counters for all matching functions that
+ has got call count breakpoints are paused at their current
+ count.
+ </p>
+ <p>Return the number of matching functions that can have
+ call count breakpoints, the same as
+ <c>start/0..3</c> with the same arguments would have
+ returned.
+ <marker id="restart"></marker>
+</p>
+ </desc>
+ </func>
+ <func>
+ <name>restart() -> integer()</name>
+ <name>restart(FuncSpec) -> integer()</name>
+ <name>restart(Mod, Func) -> integer()</name>
+ <name>restart(Mod, Func, Arity) -> integer()</name>
+ <fsummary>Restart existing call counters for matching functions.</fsummary>
+ <type>
+ <v>FuncSpec = Mod | {Mod,Func,Arity}, {FS}</v>
+ <v>Mod = atom()</v>
+ <v>Func = atom()</v>
+ <v>Arity = integer()</v>
+ <v>FS = term()</v>
+ </type>
+ <desc>
+ <p>Restart call counters for the matching functions in
+ matching modules that are call count traced. The <c>FS</c>
+ argument can be used to specify the first argument to
+ <c>erlang:trace_pattern/3</c>. See erlang(3).
+ </p>
+ <p>The call counters for all matching functions that has got
+ call count breakpoints are set to zero and running.
+ </p>
+ <p>Return the number of matching functions that can have
+ call count breakpoints, the same as
+ <c>start/0..3</c> with the same arguments would have
+ returned.
+ <marker id="start_0"></marker>
+</p>
+ </desc>
+ </func>
+ <func>
+ <name>start() -> integer()</name>
+ <fsummary>Start call count tracing for all functions.</fsummary>
+ <desc>
+ <p>Start call count tracing for all functions in all modules,
+ and also for all functions in modules to be
+ loaded. This is the same as
+ <c>(start({'_','_','_'})+start({on_load}))</c>.
+ </p>
+ <p>See also
+ <seealso marker="#start">start/1..3</seealso> below.
+ <marker id="start"></marker>
+</p>
+ </desc>
+ </func>
+ <func>
+ <name>start(FuncSpec) -> integer()</name>
+ <name>start(Mod, Func) -> integer()</name>
+ <name>start(Mod, Func, Arity) -> integer()</name>
+ <fsummary>Start call count tracing for matching functions.</fsummary>
+ <type>
+ <v>FuncSpec = Mod | {Mod,Func,Arity}, {FS}</v>
+ <v>Mod = atom()</v>
+ <v>Func = atom()</v>
+ <v>Arity = integer()</v>
+ <v>FS = term()</v>
+ </type>
+ <desc>
+ <p>Start call count tracing for matching functions in matching
+ modules. The <c>FS</c> argument can be used to specify the
+ first argument to <c>erlang:trace_pattern/3</c>, for example
+ <c>on_load</c>. See erlang(3).
+ </p>
+ <p>Set call count breakpoints on the matching functions that
+ has no call count breakpoints. Call counters
+ are set to zero and running for all matching functions.
+ </p>
+ <p>Return the number of matching functions that has got
+ call count breakpoints.
+ <marker id="stop_0"></marker>
+</p>
+ </desc>
+ </func>
+ <func>
+ <name>stop() -> integer()</name>
+ <fsummary>Stop call count tracing for all functions.</fsummary>
+ <desc>
+ <p>Stop call count tracing for all functions in all modules,
+ and also for all functions in modules to be
+ loaded. This is the same as
+ <c>(stop({'_','_','_'})+stop({on_load}))</c>.
+ </p>
+ <p>See also
+ <seealso marker="#stop">stop/1..3</seealso> below.
+ <marker id="stop"></marker>
+</p>
+ </desc>
+ </func>
+ <func>
+ <name>stop(FuncSpec) -> integer()</name>
+ <name>stop(Mod, Func) -> integer()</name>
+ <name>stop(Mod, Func, Arity) -> integer()</name>
+ <fsummary>Stop call count tracing for matching functions.</fsummary>
+ <type>
+ <v>FuncSpec = Mod | {Mod,Func,Arity}, {FS}</v>
+ <v>Mod = atom()</v>
+ <v>Func = atom()</v>
+ <v>Arity = integer()</v>
+ <v>FS = term()</v>
+ </type>
+ <desc>
+ <p>Stop call count tracing for matching functions in matching
+ modules. The <c>FS</c> argument can be used to specify the
+ first argument to <c>erlang:trace_pattern/3</c>, for example
+ <c>on_load</c>. See erlang(3).
+ </p>
+ <p>Remove call count breakpoints from the matching functions that
+ has call count breakpoints.
+ </p>
+ <p>Return the number of matching functions that can have
+ call count breakpoints, the same as
+ <c>start/0..3</c> with the same arguments would have
+ returned.
+ </p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>See Also</title>
+ <p><seealso marker="eprof">eprof</seealso>(3),
+ <seealso marker="fprof">fprof</seealso>(3),
+ erlang(3),
+ <seealso marker="cprof_chapter">User's Guide</seealso></p>
+ </section>
+</erlref>
+
diff --git a/lib/tools/doc/src/cprof_chapter.xml b/lib/tools/doc/src/cprof_chapter.xml
new file mode 100644
index 0000000000..cf6a6f843a
--- /dev/null
+++ b/lib/tools/doc/src/cprof_chapter.xml
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2002</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>cprof - The Call Count Profiler</title>
+ <prepared>Raimo Niskanen</prepared>
+ <responsible>nobody</responsible>
+ <docno></docno>
+ <approved>nobody</approved>
+ <checked>no</checked>
+ <date>2002-09-11</date>
+ <rev>PA1</rev>
+ <file>cprof_chapter.xml</file>
+ </header>
+ <p><c>cprof</c> is a profiling tool that can be used to get a picture of
+ how often different functions in the system are called.
+ </p>
+ <p><c>cprof</c> uses breakpoints similar to local call trace,
+ but containing counters, to collect profiling
+ data. Therfore there is no need for special compilation of any
+ module to be profiled.
+ </p>
+ <p><c>cprof</c> presents all profiled modules in decreasing total
+ call count order, and for each module presents all profiled
+ functions also in decreasing call count order. A call count limit
+ can be specified to filter out all functions below the limit.
+ </p>
+ <p>Profiling is done in the following steps:</p>
+ <taglist>
+ <tag><c>cprof:start/0..3</c></tag>
+ <item>Starts profiling with zeroed call counters for specified
+ functions by setting call count breakpoints on them. </item>
+ <tag><c>Mod:Fun()</c></tag>
+ <item>Runs the code to be profiled.</item>
+ <tag><c>cprof:pause/0..3</c></tag>
+ <item>Pauses the call counters for specified functions. This minimises
+ the impact of code running in the background or in the shell
+ that disturbs the profiling. Call counters are automatically
+ paused when they "hit the ceiling" of the host machine word
+ size. For a 32 bit host the maximum counter value is
+ 2147483647.</item>
+ <tag><c>cprof:analyse/0..2</c></tag>
+ <item>Collects call counters and computes the result.</item>
+ <tag><c>cprof:restart/0..3</c></tag>
+ <item>Restarts the call counters from zero for specified
+ functions. Can be used to collect a new set of counters without
+ having to stop and start call count profiling.</item>
+ <tag><c>cprof:stop/0..3</c></tag>
+ <item>Stops profiling by removing call count breakpoints from
+ specified functions.</item>
+ </taglist>
+ <p>Functions can be specified as either all in the system, all in one
+ module, all arities of one function, one function, or all
+ functions in all modules not yet loaded. As for now, BIFs cannot
+ be call count traced.
+ </p>
+ <p>The analysis result can either be for all modules, or for one
+ module. In either case a call count limit can be given to filter
+ out the functions with a call count below the limit. The all
+ modules analysis does <em>not</em> contain the module <c>cprof</c>
+ itself, it can only be analysed by specifying it as a single
+ module to analyse.
+ </p>
+ <p>Call count tracing is very lightweight compared to other forms of
+ tracing since no trace message has to be generated. Some
+ measurements indicates performance degradations in the vicinity of
+ 10 percent.
+ </p>
+ <p>The following sections show some examples of profiling with
+ <c>cprof</c>. See also
+ <seealso marker="cprof">cprof(3)</seealso>.
+ </p>
+
+ <section>
+ <title>Example: Background work</title>
+ <p>From the Erlang shell:</p>
+ <pre>
+1> <input>cprof:start(), cprof:pause(). % Stop counters just after start</input>
+3476
+2> <input>cprof:analyse().</input>
+{30,
+ [{erl_eval,11,
+ [{{erl_eval,expr,3},3},
+ {{erl_eval,'-merge_bindings/2-fun-0-',2},2},
+ {{erl_eval,expand_module_name,2},1},
+ {{erl_eval,merge_bindings,2},1},
+ {{erl_eval,binding,2},1},
+ {{erl_eval,expr_list,5},1},
+ {{erl_eval,expr_list,3},1},
+ {{erl_eval,exprs,4},1}]},
+ {orddict,8,
+ [{{orddict,find,2},6},
+ {{orddict,dict_to_list,1},1},
+ {{orddict,to_list,1},1}]},
+ {packages,7,[{{packages,is_segmented_1,1},6},
+ {{packages,is_segmented,1},1}]},
+ {lists,4,[{{lists,foldl,3},3},{{lists,reverse,1},1}]}]}
+3> <input>cprof:analyse(cprof).</input>
+{cprof,3,[{{cprof,tr,2},2},{{cprof,pause,0},1}]}
+4> <input>cprof:stop().</input>
+3476</pre>
+ <p>The example showed the background work that the shell performs
+ just to interpret the first command line. Most work is done by
+ <c>erl_eval</c> and <c>orddict</c>.
+ </p>
+ <p>What is captured in this example is the part of the work the
+ shell does while interpreting the command line that occurs
+ between the actual calls to <c>cprof:start()</c> and
+ <c>cprof:analyse()</c>.
+ </p>
+ </section>
+
+ <section>
+ <title>Example: One module</title>
+ <p>From the Erlang shell:</p>
+ <pre>
+1> <input>cprof:start(),R=calendar:day_of_the_week(1896,4,27),cprof:pause(),R.</input>
+1
+2> <input>cprof:analyse(calendar).</input>
+{calendar,9,
+ [{{calendar,df,2},1},
+ {{calendar,dm,1},1},
+ {{calendar,dy,1},1},
+ {{calendar,last_day_of_the_month1,2},1},
+ {{calendar,last_day_of_the_month,2},1},
+ {{calendar,is_leap_year1,1},1},
+ {{calendar,is_leap_year,1},1},
+ {{calendar,day_of_the_week,3},1},
+ {{calendar,date_to_gregorian_days,3},1}]}
+3> <input>cprof:stop().</input>
+3271</pre>
+ <p>The example tells us that "Aktiebolaget LM Ericsson &amp; Co"
+ was registered on a Monday (since the return value
+ of the first command is 1), and that the <c>calendar</c> module
+ needed 9 function calls to calculate that.
+ </p>
+ <p>Using <c>cprof:analyse()</c> in this example also shows
+ approximately the same background work as in the first example.
+ </p>
+ </section>
+
+ <section>
+ <title>Example: In the code</title>
+ <p>Write a module:</p>
+ <pre>
+-module(sort).
+
+-export([do/1]).
+
+do(N) ->
+ cprof:stop(),
+ cprof:start(),
+ do(N, []).
+
+do(0, L) ->
+ R = lists:sort(L),
+ cprof:pause(),
+ R;
+do(N, L) ->
+ do(N-1, [random:uniform(256)-1 | L]).</pre>
+ <p>From the Erlang shell:</p>
+ <pre>
+1> <input>c(sort).</input>
+{ok,sort}
+2> <input>l(random).</input>
+{module,random}
+3> <input>sort:do(1000).</input>
+[0,0,1,1,1,1,1,1,2,2,2,3,3,3,3,3,4,4,4,5,5,5,5,6,6,6,6,6,6|...]
+4> <input>cprof:analyse().</input>
+{9050,
+ [{lists_sort,6047,
+ [{{lists_sort,merge3_2,6},923},
+ {{lists_sort,merge3_1,6},879},
+ {{lists_sort,split_2,5},661},
+ {{lists_sort,rmerge3_1,6},580},
+ {{lists_sort,rmerge3_2,6},543},
+ {{lists_sort,merge3_12_3,6},531},
+ {{lists_sort,merge3_21_3,6},383},
+ {{lists_sort,split_2_1,6},338},
+ {{lists_sort,rmerge3_21_3,6},299},
+ {{lists_sort,rmerge3_12_3,6},205},
+ {{lists_sort,rmerge2_2,4},180},
+ {{lists_sort,rmerge2_1,4},171},
+ {{lists_sort,merge2_1,4},127},
+ {{lists_sort,merge2_2,4},121},
+ {{lists_sort,mergel,2},79},
+ {{lists_sort,rmergel,2},27}]},
+ {random,2001,
+ [{{random,uniform,1},1000},
+ {{random,uniform,0},1000},
+ {{random,seed0,0},1}]},
+ {sort,1001,[{{sort,do,2},1001}]},
+ {lists,1,[{{lists,sort,1},1}]}]}
+5> <input>cprof:stop().</input>
+5369</pre>
+ <p>The example shows some details of how <c>lists:sort/1</c>
+ works. It used 6047 function calls in the module
+ <c>lists_sort</c> to complete the work.
+ </p>
+ <p>This time, since the shell was not involved, no other work was
+ done in the system during the profiling. If you retry the same
+ example with a freshly started Erlang emulator, but omit the
+ command <c>l(random)</c>, the analysis will show a lot more
+ function calls done by <c>code_server</c> and others to
+ automatically load the module <c>random</c>.
+ </p>
+ </section>
+</chapter>
+
diff --git a/lib/tools/doc/src/eprof.xml b/lib/tools/doc/src/eprof.xml
new file mode 100644
index 0000000000..ae1033f2d0
--- /dev/null
+++ b/lib/tools/doc/src/eprof.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>eprof</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <module>eprof</module>
+ <modulesummary>A Time Profiling Tool for Erlang</modulesummary>
+ <description>
+ <p>The module <c>eprof</c> provides a set of functions for time
+ profiling of Erlang programs to find out how the execution time is
+ used. The profiling is done using the Erlang trace BIFs. Tracing of
+ local function calls for a specified set of processes is enabled when
+ profiling is begun, and disabled when profiling is stopped.</p>
+ <p>When using Eprof, expect a significant slowdown in program execution,
+ in most cases at least 100 percent.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>start() -> {ok,Pid} | {error,Reason}</name>
+ <fsummary>Start Eprof.</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ <v>Reason = {already_started,Pid}</v>
+ </type>
+ <desc>
+ <p>Starts the Eprof server which owns the Eprof internal database.</p>
+ </desc>
+ </func>
+ <func>
+ <name>start_profiling(Rootset) -> profiling | error</name>
+ <name>profile(Rootset) -> profiling | error</name>
+ <fsummary>Start profiling.</fsummary>
+ <type>
+ <v>Rootset = [atom() | pid()]</v>
+ </type>
+ <desc>
+ <p>Starts profiling for the processes in <c>Rootset</c> (and any new
+ processes spawned from them). Information about activity in any
+ profiled process is stored in the Eprof database.</p>
+ <p><c>Rootset</c> is a list of pids and registered names.</p>
+ <p>The function returns <c>profiling</c> if tracing could be enabled
+ for all processes in <c>Rootset</c>, or <c>error</c> otherwise.</p>
+ </desc>
+ </func>
+ <func>
+ <name>stop_profiling() -> profiling_stopped | profiling_already_stopped</name>
+ <fsummary>Stop profiling.</fsummary>
+ <desc>
+ <p>Stops profiling started with <c>start_profiling/1</c> or
+ <c>profile/1</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>profile(Rootset,Fun) -> {ok,Value} | {error,Reason} | error</name>
+ <name>profile(Rootset,Module,Function,Args) -> {ok,Value} | {error,Reason} | error</name>
+ <fsummary>Start profiling.</fsummary>
+ <type>
+ <v>Rootset = [atom() | pid()]</v>
+ <v>Fun = fun() -> term()</v>
+ <v>Module = Function = atom()</v>
+ <v>Args = [term()]</v>
+ <v>Value = Reason = term()</v>
+ </type>
+ <desc>
+ <p>This function first spawns a process <c>P</c> which evaluates
+ <c>Fun()</c> or <c>apply(Module,Function,Args)</c>. Then, it
+ starts profiling for <c>P</c> and the processes in <c>Rootset</c>
+ (and any new processes spawned from them). Information about
+ activity in any profiled process is stored in the Eprof database.</p>
+ <p><c>Rootset</c> is a list of pids and registered names.</p>
+ <p>If tracing could be enabled for <c>P</c> and all processes in
+ <c>Rootset</c>, the function returns <c>{ok,Value}</c> when
+ <c>Fun()</c>/<c>apply</c> returns with the value <c>Value</c>, or
+ <c>{error,Reason}</c> if <c>Fun()</c>/<c>apply</c> fails with
+ exit reason <c>Reason</c>. Otherwise it returns <c>error</c>
+ immediately.</p>
+ <p>The programmer must ensure that the function given as argument
+ is truly synchronous and that no work continues after
+ the function has returned a value.</p>
+ </desc>
+ </func>
+ <func>
+ <name>analyse()</name>
+ <fsummary>Display profiling results per process.</fsummary>
+ <desc>
+ <p>Call this function when profiling has been stopped to display
+ the results per process, that is:</p>
+ <list type="bulleted">
+ <item>how much time has been used by each process, and</item>
+ <item>in which function calls this time has been spent.</item>
+ </list>
+ <p>Time is shown as percentage of total time, not as absolute time.</p>
+ </desc>
+ </func>
+ <func>
+ <name>total_analyse()</name>
+ <fsummary>Display profiling results per function call.</fsummary>
+ <desc>
+ <p>Call this function when profiling has been stopped to display
+ the results per function call, that is in which function calls
+ the time has been spent.</p>
+ <p>Time is shown as percentage of total time, not as absolute time.</p>
+ </desc>
+ </func>
+ <func>
+ <name>log(File) -> ok</name>
+ <fsummary>Activate logging of <c>eprof</c>printouts.</fsummary>
+ <type>
+ <v>File = atom() | string()</v>
+ </type>
+ <desc>
+ <p>This function ensures that the results displayed by
+ <c>analyse/0</c> and <c>total_analyse/0</c> are printed both to
+ the file <c>File</c> and the screen.</p>
+ </desc>
+ </func>
+ <func>
+ <name>stop() -> stopped</name>
+ <fsummary>Stop Eprof.</fsummary>
+ <desc>
+ <p>Stops the Eprof server.</p>
+ </desc>
+ </func>
+ </funcs>
+</erlref>
+
diff --git a/lib/tools/doc/src/erlang_mode.xml b/lib/tools/doc/src/erlang_mode.xml
new file mode 100644
index 0000000000..72770898c2
--- /dev/null
+++ b/lib/tools/doc/src/erlang_mode.xml
@@ -0,0 +1,324 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2003</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Erlang mode for Emacs</title>
+ <prepared>Ingela Anderton</prepared>
+ <responsible></responsible>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <module>erlang.el</module>
+ <modulesummary>Erlang mode for Emacs </modulesummary>
+ <description>
+ <p>Possibly the most important feature of an editor designed for
+ programmers is the ability to indent a line of code in accordance
+ with the structure of the programming language. The Erlang mode
+ does, of course, provide this feature. The layout used is based
+ on the common use of the language. The mode also provides things as
+ syntax highlighting, electric commands, module name verification,
+ comment support including paragraph filling, skeletons, tags
+ support etc.</p>
+ <p>In the following descriptions the use of the word <em>Point</em> means: "Point can be seen as the position of the
+ cursor. More precisely, the point is the position between two
+ characters while the cursor is drawn over the character
+ following the point".</p>
+ </description>
+
+ <section>
+ <title>Indent</title>
+ <p>The following command are directly available for indentation.</p>
+ <list type="bulleted">
+ <item><em><c>TAB</c></em> (<c>erlang-indent-command</c>) -
+ Indents the current line of code. </item>
+ <item><em><c>M-C-\\</c></em> (<c>indent-region</c>) - Indents all
+ lines in the region. </item>
+ <item><em><c>M-l</c></em> (<c>indent-for-comment</c>) - Insert a
+ comment character to the right of the code on the line (if
+ any).</item>
+ </list>
+ <p>Lines containing comment are indented differently depending on
+ the number of %-characters used: </p>
+ <list type="bulleted">
+ <item>Lines with one %-character is indented to the right of
+ the code. The column is specified by the variable
+ <c>comment-column</c>, by default column 48 is used.</item>
+ <item>Lines with two %-characters will be indented to the same
+ depth as code would have been in the same situation. </item>
+ <item>Lines with three of more %-characters are indented to the
+ left margin.</item>
+ <item><em><c>C-c C-q</c></em> (<c>erlang-indent-function</c>) -
+ Indents the current Erlang function. </item>
+ <item><em><c>M-x erlang-indent-clause RET</c></em> <br></br>
+ -Indent the
+ current Erlang clause.</item>
+ <item><em><c>M-x erlang-indent-current-buffer RET</c></em> -
+ Indent the entire buffer. </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Edit - Fill Comment </title>
+ <p>When editing normal text in text mode you can let Emacs reformat the
+ text by the <c>fill-paragraph</c> command. This command will not work
+ for comments since it will treat the comment characters as words.</p>
+ <p>The Erlang editing mode provides a command that knows about the
+ Erlang comment structure and can be used to fill text paragraphs
+ in comments. Ex:</p>
+ <code type="none">
+ %% This is just a very simple test to show
+ %% how the Erlang fill
+ %% paragraph command works.</code>
+ <p>Clearly, the text is badly formatted. Instead of formatting this
+ paragraph line by line, let's try <c>erlang-fill-paragraph</c> by
+ pressing <em><c>M-q</c></em>. The result is:</p>
+ <code type="none">
+ %% This is just a very simple test to show how the Erlang fill
+ %% paragraph command works.</code>
+ </section>
+
+ <section>
+ <title>Edit - Comment/Uncomment Region </title>
+ <p><em><c>C-c C-c</c></em> will put comment characters at the
+ beginning of all lines in a marked region. If you want to have
+ two comment characters instead of one you can do <em><c>C-u 2 C-c C-c</c></em></p>
+ <p><em><c>C-c C-u</c></em> will undo a comment-region command. </p>
+ </section>
+
+ <section>
+ <title>Edit - Moving the marker </title>
+ <list type="bulleted">
+ <item><em><c>C-a M-a </c></em>
+ (<c>erlang-beginning-of-function</c>) - Move the point to the
+ beginning of the current or preceding Erlang function. With an
+ numeric argument (ex <em><c>C-u 2 C-a M-a</c></em>) the function
+ skips backwards over this many Erlang functions. Should the
+ argument be negative the point is moved to the beginning of a
+ function below the current function. </item>
+ <item><em><c>M-C-a </c></em> (<c>erlang-beginning-of-clause</c>) - As
+ above but move point to the beginning of the current or
+ preceding Erlang clause.</item>
+ <item><em><c>C-a M-e </c></em> (<c>erlang-end-of-function</c>)
+ - Move to the end of the current or following Erlang function. With
+ an numeric argument (ex <em><c>C-u 2 C-a M-e</c></em>) the function
+ skips backwards over this many Erlang functions. Should the argument
+ be negative the point is moved to the end of a function below
+ the current function.</item>
+ <item><em><c>M-C-e </c></em> (<c>erlang-end-of-clause</c>) - As above
+ but move point to the end of the current or following Erlang
+ clause.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Edit - Marking </title>
+ <list type="bulleted">
+ <item><em><c>C-c M-h</c></em> (<c>erlang-mark-function</c>) - Put the
+ region around the current Erlang function. The point is
+ placed in the beginning and the mark at the end of the
+ function.</item>
+ <item><em><c>M-C-h </c></em> (<c>erlang-mark-clause</c>) Put the region
+ around the current Erlang clause. The point is placed in the
+ beginning and the mark at the end of the function. </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Edit - Function Header Commands </title>
+ <list type="bulleted">
+ <item><em><c>C-c C-j</c></em> (<c>erlang-generate-new-clause</c>) -
+ Create a new clause in the current Erlang function. The point is
+ placed between the parentheses of the argument list.</item>
+ <item><em><c>C-c C-y</c></em> (<c>erlang-clone-arguments</c>) -
+ Copy the function arguments of the preceding Erlang clause. This
+ command is useful when defining a new clause with almost the same
+ argument as the preceding.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Edit - Arrows</title>
+ <list type="bulleted">
+ <item>
+ <p><em><c>C-c C-a</c></em> (<c>erlang-align-arrows</c>) -
+ aligns arrows after clauses inside a region.</p>
+ <code type="none">
+ Example:
+
+ sum(L) -> sum(L, 0).
+ sum([H|T], Sum) -> sum(T, Sum + H);
+ sum([], Sum) -> Sum.
+
+ becomes:
+
+ sum(L) -> sum(L, 0).
+ sum([H|T], Sum) -> sum(T, Sum + H);
+ sum([], Sum) -> Sum."</code>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Syntax highlighting</title>
+ <p>The syntax highlighting can be activated from the Erlang menu. There
+ are four different alternatives:</p>
+ <list type="bulleted">
+ <item>Off: Normal black and white display.
+ </item>
+ <item>Level 1: Function headers, reserved words, comments,
+ strings, quoted atoms, and character constants will be
+ colored. </item>
+ <item>Level 2: The above, attributes, Erlang bif:s, guards, and
+ words in comments enclosed in single quotes will be colored.</item>
+ <item>Level 3: The above, variables, records, and macros will
+ be colored. (This level is also known as the Christmas tree
+ level.) </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Tags</title>
+ <p>For the tag commands to work it requires that you have
+ generated a tag file. See <seealso marker="erlang_mode_chapter#tags">Erlang mode users guide</seealso></p>
+ <p></p>
+ <list type="bulleted">
+ <item><em><c>M-. </c></em> (<c>find-tag</c>) -
+ Find a function definition. The default value is the function name
+ under the point. </item>
+ <item>Find Tag (<c>erlang-find-tag</c>) - Like the Elisp-function
+ `find-tag'. Capable of retrieving Erlang modules. Tags can be
+ given on the forms `tag', `module:', `module:tag'.</item>
+ <item><em><c>M-+</c></em> (<c>erlang-find-next-tag</c>) - Find the
+ next occurrence of tag.</item>
+ <item><em><c>M-TAB</c></em> (<c>erlang-complete-tag</c>) -
+ Perform completion on the tag entered in a tag search.
+ Completes to the set of names listed in the current tags table.</item>
+ <item>Tags aprops (<c>tags-apropos</c>) - Display list of all tags in
+ tags table REGEXP matches. </item>
+ <item><em><c>C-x t s</c></em> (<c>tags-search</c>) - Search
+ through all files listed in tags table for match for REGEXP.
+ Stops when a match is found.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Skeletons</title>
+ <p>A skeleton is a piece of pre-written code that can be inserted into
+ the buffer. Erlang mode comes with a set of predefined skeletons.
+ The skeletons can be accessed either from the Erlang menu of
+ from commands named <c>tempo-template-erlang-*</c>, as the
+ skeletons is defined using the standard Emacs package "tempo".
+ Here follows a brief description of the available skeletons:</p>
+ <list type="bulleted">
+ <item>Simple skeletons: If, Case, Receive, Receive After,
+ Receive Loop - Basic code constructs.
+ </item>
+ <item>Header elements: Module, Author - These commands insert
+ lines on the form <c>-module(</c>xxx<c>). </c> and
+ <c>-author('my@home').</c>. They can be used directly, but are
+ also used as part of the full headers described below.</item>
+ <item>Full Headers: Small (minimum requirement), Medium (with
+ fields for basic information about the module), and Large
+ Header (medium header with some extra layout structure).</item>
+ <item>Small Server - skeleton for a simple server not using
+ OTP.</item>
+ <item>Application - skeletons for the OTP application
+ behavior</item>
+ <item>Supervisor - skeleton for the OTP supervisor behavior</item>
+ <item>Supervisor Bridge - skeleton for the OTP supervisor bridge
+ behavior </item>
+ <item>gen_server - skeleton for the OTP gen_server
+ behavior</item>
+ <item>gen_event - skeleton for the OTP gen_event behavior</item>
+ <item>gen_fsm - skeleton for the OTP gen_fsm behavior</item>
+ <item>Library module - skeleton for a module that does not
+ implement a process.</item>
+ <item>Corba callback - skeleton for a Corba callback module.</item>
+ <item>Erlang test suite - skeleton for a callback module
+ for the erlang test server.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Shell</title>
+ <list type="bulleted">
+ <item>New shell (<c>erlang-shell</c>) - Starts a new Erlang shell.</item>
+ <item><em><c>C-c C-z,</c></em> (<c>erlang-shell-display </c>) -
+ Displays an Erlang shell, or starts a new one if there is no shell
+ started.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Compile</title>
+ <list type="bulleted">
+ <item><em><c>C-c C-k,</c></em> (<c>erlang-compile</c>) -
+ Compiles the Erlang module in the current buffer.
+ You can also use <em><c>C-u C-c C-k</c></em>
+ to debug compile the module with the debug options
+ <c>debug_info</c> and <c>export_all</c>.</item>
+ <item><em><c>C-c C-l,</c></em> (<c>erlang-compile-display</c>) -
+ Display compilation output.</item>
+ <item><em><c>C-u C-x`</c></em> Start parsing the compiler output from the
+ beginning. This command will place the point on the line where
+ the first error was found.</item>
+ <item><em><c>C-x`</c></em> (<c>erlang-next-error</c>) - Move the
+ point on to the next error. The buffer displaying the
+ compilation errors will be updated so that the current error
+ will be visible.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Man</title>
+ <p>On unix you can view the manual pages in emacs.
+ In order to find the manual pages, the variable `erlang-root-dir'
+ should be bound to the name of the directory containing the Erlang
+ installation. The name should not include the final slash.
+ Practically, you should add a line on the following form to
+ your ~/.emacs,</p>
+ <code type="none">
+ (setq erlang-root-dir "/the/erlang/root/dir/goes/here")</code>
+ </section>
+
+ <section>
+ <title>Starting IMenu</title>
+ <list type="bulleted">
+ <item><em><c>M-x imenu-add-to-menubar RET</c></em> - This
+ command will create the IMenu menu containing all the functions
+ in the current buffer.The command will ask you for a suitable
+ name for the menu. Not supported by Xemacs.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Version</title>
+ <list type="bulleted">
+ <item><em><c>M-x erlang-version RET</c></em> -
+ This command displays the version number of the Erlang editing mode.
+ Remember to always supply the version number when asking questions
+ about the Erlang mode.</item>
+ </list>
+ </section>
+</erlref>
+
diff --git a/lib/tools/doc/src/erlang_mode_chapter.xml b/lib/tools/doc/src/erlang_mode_chapter.xml
new file mode 100644
index 0000000000..cf043e3302
--- /dev/null
+++ b/lib/tools/doc/src/erlang_mode_chapter.xml
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2003</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>The Erlang mode for Emacs</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>erlang_mode_chapter.xml</file>
+ </header>
+
+ <section>
+ <title>Purpose</title>
+ <p>The purpose of this user guide is to introduce you to the
+ Erlang mode for Emacs and gives some relevant background
+ information of the functions and features. See also <seealso marker="erlang.el">Erlang mode reference manual</seealso> The
+ purpose of the Erlang mode itself is to facilitate the developing
+ process for the Erlang programmer.</p>
+ </section>
+
+ <section>
+ <title>Pre-requisites</title>
+ <p>Basic knowledge of Emacs and Erlang/OTP. </p>
+ </section>
+
+ <section>
+ <title>Elisp</title>
+ <p>There are two Elsip modules include in this tool package
+ for Emacs. There is erlang.el that defines the actual erlang mode
+ and there is erlang-start.el that makes some nice initializations.</p>
+ </section>
+
+ <section>
+ <title>Setup on UNIX</title>
+ <p>To set up the Erlang Emacs mode on a UNIX systems, edit/create
+ the file <c>.emacs</c> in the your home directory.</p>
+ <p>Below is a complete example of what should be added to a user's
+ <c>.emacs</c> provided that OTP is installed in the directory
+ <c>/usr/local/otp </c>: </p>
+ <code type="none"><![CDATA[
+ (setq load-path (cons "/usr/local/otp/lib/tools-<ToolsVer>/emacs"
+ load-path))
+ (setq erlang-root-dir "/usr/local/otp")
+ (setq exec-path (cons "/usr/local/otp/bin" exec-path))
+ (require 'erlang-start)
+ ]]></code>
+ </section>
+
+ <section>
+ <title>Setup on Windows </title>
+ <p>To set up the Erlang Emacs mode on a Windows systems,
+ edit/create the file <c>.emacs</c>, the location of the file
+ depends on the configuration of the system. If the <em>HOME</em>
+ environment variable is set, Emacs will look for the
+ <c>.emacs</c> file in the directory indicated by the
+ <em>HOME</em> variable. If <em>HOME</em> is not set, Emacs
+ will look for the <c>.emacs</c> file in <c>C:\\ </c>.</p>
+ <p>Below is a complete example of what should be added to a user's
+ <c>.emacs</c> provided that OTP is installed in the directory
+ <c><![CDATA[C:\\Program Files\\erl<Ver>]]></c>: </p>
+ <code type="none"><![CDATA[
+ (setq load-path (cons "C:/Program Files/erl<Ver>/lib/tools-<ToolsVer>/emacs"
+ load-path))
+ (setq erlang-root-dir "C:/Program Files/erl<Ver>")
+ (setq exec-path (cons "C:/Program Files/erl<Ver>/bin" exec-path))
+ (require 'erlang-start)
+ ]]></code>
+ <note>
+ <p>In .emacs, the slash character "/" can be used as path
+ separator. But if you decide to use the backslash character "\\",
+ please not that you must use double backslashes, since they are
+ treated as escape characters by Emacs.</p>
+ </note>
+ </section>
+
+ <section>
+ <title>Indentation</title>
+ <p>The "Oxford Advanced Learners Dictionary of Current English" says the
+ following about the word "indent":</p>
+ <quote>
+ <p>"start (a line of print or writing) farther from
+ the margin than the others".</p>
+ </quote>
+ <p>The Erlang mode does, of course, provide this feature. The layout
+ used is based on the common use of the language.</p>
+ <p>It is strongly recommend to use this feature and avoid to indent lines
+ in a nonstandard way. Some motivations are:</p>
+ <list type="bulleted">
+ <item>Code using the same layout is easy to read and maintain. </item>
+ <item>Since several features of Erlang mode is based on the
+ standard layout they might not work correctly if a nonstandard layout
+ is used. </item>
+ </list>
+ <p>The indentation features can be used to reindent large sections
+ of a file. If some lines use nonstandard indentation they will
+ be reindented.</p>
+ </section>
+
+ <section>
+ <title>Editing</title>
+ <list type="bulleted">
+ <item><em><c>M-x erlang-mode RET</c></em> - This command activates
+ the Erlang major mode for the current buffer. When this
+ mode is active the mode line contain the word "Erlang".</item>
+ </list>
+ <p>When the Erlang mode is correctly installed, it is
+ automatically activated when a file ending in <c>.erl</c> or
+ <c>.hrl</c> is opened in Emacs.</p>
+ <p>When a file is saved the name in the <c>-module().</c> line is
+ checked against the file name. Should they mismatch Emacs can
+ change the module specifier so that it matches the file name.
+ By default, the user is asked before the change is performed.</p>
+ <p>An "electric" command is a character that in addition to just
+ inserting the character performs some type of action. For
+ example the ";" character is typed in a situation where is ends
+ a function clause a new function header is generated. The electric
+ commands are as follows: </p>
+ <list type="bulleted">
+ <item><em><c>erlang-electric-comma</c></em> - Insert a comma
+ character and possibly a new indented line. </item>
+ <item><em><c>erlang-electric-semicolon</c></em> - Insert a
+ semicolon character and possibly a prototype for the next line.</item>
+ <item><em><c>erlang-electric-gt</c></em> - "Insert a '>'-sign
+ and possible a new indented line.</item>
+ </list>
+ <p>To disable all electric commands set the variable
+ <c>erlang-electric-commands</c> to the empty list. In short,
+ place the following line in your <c>.emacs</c>-file:</p>
+ <code type="none">
+ (setq erlang-electric-commands '())</code>
+ </section>
+
+ <section>
+ <title>Syntax highlighting</title>
+ <p>It is possible for Emacs to use colors when displaying a buffer. By
+ "syntax highlighting", we mean that syntactic components, for example
+ keywords and function names, will be colored.</p>
+ <p>The basic idea of syntax highlighting is to make the structure of a
+ program clearer. For example, the highlighting will make it easier to
+ spot simple bugs. Have not you ever written a variable in lower-case
+ only? With syntax highlighting a variable will colored while atoms
+ will be shown with the normal text color.</p>
+ </section>
+
+ <section>
+ <marker id="tags"></marker>
+ <title>Tags</title>
+ <p>Tags is a standard Emacs package used to record information
+ about source files in large development projects. In addition to
+ listing the files of a project, a tags file normally contains
+ information about all functions and variables that are defined.
+ By far, the most useful command of the tags system is its ability
+ to find the definition of functions in any file in the project.
+ However the Tags system is not limited to this feature, for
+ example, it is possible to do a text search in all files in a
+ project, or to perform a project-wide search and replace.</p>
+ <p>In order to use the Tags system a file named <c>TAGS</c> must be
+ created. The file can be seen as a database over all functions,
+ records, and macros in all files in the project. The
+ <c>TAGS</c> file can be created using two different methods for
+ Erlang. The first is the standard Emacs utility "etags", the
+ second is by using the Erlang module <c>tags</c>.</p>
+ </section>
+
+ <section>
+ <title>Etags</title>
+ <p><c>etags</c> is a program that is part of the Emacs
+ distribution. It is normally executed from a command line, like
+ a unix shell or a DOS box.</p>
+ <p>The <c>etags</c> program of fairly modern versions of Emacs and XEmacs
+ has native support for Erlang. To check if your version does include
+ this support, issue the command <c>etags --help</c> at a the command
+ line prompt. At the end of the help text there is a list of supported
+ languages. Unless Erlang is a member of this list I suggest that you
+ should upgrade to a newer version of Emacs.</p>
+ <p>As seen in the help text -- unless you have not upgraded your
+ Emacs yet (well, what are you waiting around here for? Off you go and
+ upgrade!) -- <c>etags</c> associate the file extensions <c>.erl</c>
+ and <c>.hrl</c> with Erlang.</p>
+ <p>Basically, the <c>etags</c> utility is ran using the following form:</p>
+ <code type="none">
+ etags file1.erl file2.erl</code>
+ <p>This will create a file named <c>TAGS</c> in the current directory.</p>
+ <p>The <c>etags</c> utility can also read a list of files from its
+ standard input by supplying a single dash in place of the file
+ names. This feature is useful when a project consists of a
+ large number of files. The standard UNIX command <c>find</c>
+ can be used to generate the list of files, e.g:</p>
+ <code type="none">
+ find . -name "*.[he]rl" -print | etags -</code>
+ <p>The above line will create a <c>TAGS</c> file covering all the
+ Erlang source files in the current directory, and in the
+ subdirectories below.</p>
+ <p>Please see the GNU Emacs Manual and the etags man page for more
+ info.</p>
+ </section>
+
+ <section>
+ <title>Shell</title>
+ <p>The look and feel on an Erlang shell inside Emacs should be the
+ same as in a normal Erlang shell. There is just one major
+ difference, the cursor keys will actually move the cursor around
+ just like in any normal Emacs buffer. The command line history
+ can be accessed by the following commands: </p>
+ <list type="bulleted">
+ <item><em><c>C-up </c></em> or <em><c>M-p </c></em>
+ (<c>comint-previous-input</c>) -
+ Move to the previous line in the input history.</item>
+ <item><em><c>C-down </c></em> or <em><c>M-n </c></em>
+ (<c>comint-next-input</c>) - Move to the next line in the
+ input history.</item>
+ </list>
+ <p>If the Erlang shell buffer would be killed the command line
+ history is saved to a file. The command line history is
+ automatically retrieved when a new Erlang shell is started.</p>
+ </section>
+
+ <section>
+ <title>Compilation</title>
+ <p>The classic edit-compile-bugfix cycle for Erlang is to edit the
+ source file in an editor, save it to a file and switch to an
+ Erlang shell. In the shell the compilation command is given.
+ Should the compilation fail you have to bring out the editor and
+ locate the correct line.</p>
+ <p>With the Erlang editing mode the entire edit-compile-bugfix cycle can
+ be performed without leaving Emacs. Emacs can order Erlang to compile
+ a file and it can parse the error messages to automatically place the
+ point on the erroneous lines.</p>
+ </section>
+</chapter>
+
diff --git a/lib/tools/doc/src/fascicules.xml b/lib/tools/doc/src/fascicules.xml
new file mode 100644
index 0000000000..0678195e07
--- /dev/null
+++ b/lib/tools/doc/src/fascicules.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
+
+<fascicules>
+ <fascicule file="part" href="part_frame.html" entry="no">
+ User's Guide
+ </fascicule>
+ <fascicule file="ref_man" href="ref_man_frame.html" entry="yes">
+ Reference Manual
+ </fascicule>
+ <fascicule file="part_notes" href="part_notes_frame.html" entry="no">
+ Release Notes
+ </fascicule>
+ <fascicule file="" href="../../../../doc/print.html" entry="no">
+ Off-Print
+ </fascicule>
+</fascicules>
+
diff --git a/lib/tools/doc/src/fprof.xml b/lib/tools/doc/src/fprof.xml
new file mode 100644
index 0000000000..8babf50033
--- /dev/null
+++ b/lib/tools/doc/src/fprof.xml
@@ -0,0 +1,911 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2001</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>fprof</title>
+ <prepared>Raimo Niskanen</prepared>
+ <responsible>nobody</responsible>
+ <docno></docno>
+ <approved>nobody</approved>
+ <checked></checked>
+ <date>2001-08-13</date>
+ <rev>PA1</rev>
+ <file>fprof.sgml</file>
+ </header>
+ <module>fprof</module>
+ <modulesummary>A Time Profiling Tool using trace to file for minimal runtime performance impact.</modulesummary>
+ <description>
+ <p>This module is used to profile a program
+ to find out how the execution time is used.
+ Trace to file is used to minimize
+ runtime performance impact.
+ </p>
+ <p>The <c>fprof</c> module uses tracing to collect profiling data,
+ hence there is no need for special compilation of any module to
+ be profiled. When it starts tracing, <c>fprof</c> will erase all
+ previous tracing in the node and set the necessary trace flags
+ on the profiling target processes as well as local call trace on
+ all functions in all loaded modules and all modules to be loaded.
+ <c>fprof</c> erases all tracing in the node when it stops tracing.
+ </p>
+ <p><c>fprof</c> presents both <em>own time</em> i.e how much time a
+ function has used for its own execution, and
+ <em>accumulated time</em> i.e including called functions.
+ All presented times are
+ collected using trace timestamps. <c>fprof</c> tries to collect
+ cpu time timestamps, if the host machine OS supports it.
+ Therefore the times may be wallclock times and OS scheduling will
+ randomly strike all called functions in a presumably fair way.
+ </p>
+ <p>If, however, the profiling time is short, and the host machine
+ OS does not support high resolution cpu time measurements, some
+ few OS schedulings may show up as ridiculously long execution
+ times for functions doing practically nothing. An example of a
+ function more or less just composing a tuple in about 100 times
+ the normal execution time has been seen, and when the tracing
+ was repeated, the execution time became normal.
+ </p>
+ <p>Profiling is essentially done in 3 steps:</p>
+ <taglist>
+ <tag><c>1</c></tag>
+ <item>Tracing; to file, as mentioned in the previous
+ paragraph. The trace contains entries for function calls,
+ returns to function, process scheduling, other process related
+ (spawn, etc) events, and garbage collection. All trace entries
+ are timestamped.</item>
+ <tag><c>2</c></tag>
+ <item>Profiling; the trace file is read, the execution call
+ stack is simulated, and raw profile data is calculated from
+ the simulated call stack and the trace timestamps. The profile
+ data is stored in the <c>fprof</c> server state. During this
+ step the trace data may be dumped in text format to file or
+ console. </item>
+ <tag><c>3</c></tag>
+ <item>Analysing; the raw profile data is sorted, filtered and
+ dumped in text format either to file or console. The text
+ format intended to be both readable for a human reader, as
+ well as parsable with the standard erlang parsing tools.</item>
+ </taglist>
+ <p>Since <c>fprof</c> uses trace to file, the runtime performance
+ degradation is minimized, but still far from negligible,
+ especially for programs that use the filesystem heavily by
+ themselves. Where you place the trace file is also important,
+ e.g on Solaris <c>/tmp</c> is usually a good choice since it is
+ essentially a RAM disk, while any NFS (network) mounted disk is
+ a bad idea.
+ </p>
+ <p><c>fprof</c> can also skip the file step and trace to a tracer
+ process that does the profiling in runtime.
+ <marker id="start"></marker>
+</p>
+ </description>
+ <funcs>
+ <func>
+ <name>start() -> {ok, Pid} | {error, {already_started, Pid}}</name>
+ <fsummary>Starts the <c>fprof</c>&nbsp;server.</fsummary>
+ <type>
+ <v>Pid = pid()</v>
+ </type>
+ <desc>
+ <p>Starts the <c>fprof</c>&nbsp;server.
+ </p>
+ <p>Note that it seldom
+ needs to be started explicitly since it is automatically
+ started by the functions that need a running server.
+ <marker id="stop"></marker>
+</p>
+ </desc>
+ </func>
+ <func>
+ <name>stop() -> ok</name>
+ <fsummary>Same as <c>stop(normal)</c>.</fsummary>
+ <desc>
+ <p>Same as <c>stop(normal)</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>stop(Reason) -> ok</name>
+ <fsummary>Stops the <c>fprof</c>&nbsp;server.</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Stops the <c>fprof</c>&nbsp;server.
+ </p>
+ <p>The supplied <c>Reason</c> becomes the exit reason for the
+ server process. Default Any
+ <c>Reason</c> other than <c>kill</c> sends a request to the
+ server and waits for it to clean up, reply and exit. If
+ <c>Reason</c> is <c>kill</c>, the server is bluntly killed.
+ </p>
+ <p>If the <c>fprof</c>&nbsp;server is not running, this
+ function returns immediately with the same return value.
+ </p>
+ <note>
+ <p>When the <c>fprof</c>&nbsp;server is stopped the
+ collected raw profile data is lost.</p>
+ </note>
+ <marker id="apply"></marker>
+ </desc>
+ </func>
+ <func>
+ <name>apply(Func, Args) -> term()</name>
+ <fsummary>Same as <c>apply(Func, Args, [])</c>.</fsummary>
+ <type>
+ <v>Func = function() | {Module, Function}</v>
+ <v>Args = [term()]</v>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ </type>
+ <desc>
+ <p>Same as <c>apply(Func, Args, [])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>apply(Module, Function, Args) -> term()</name>
+ <fsummary>Same as <c>apply({Module, Function}, Args, [])</c>.</fsummary>
+ <type>
+ <v>Args = [term()]</v>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ </type>
+ <desc>
+ <p>Same as <c>apply({Module, Function}, Args, [])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>apply(Func, Args, OptionList) -> term()</name>
+ <fsummary>Calls <c>erlang:apply(Func, Args)</c>surrounded by<c>trace([start | OptionList])</c>and<c>trace(stop)</c>.</fsummary>
+ <type>
+ <v>Func = function() | {Module, Function}</v>
+ <v>Args = [term()]</v>
+ <v>OptionList = [Option]</v>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ <v>Option = continue | start | {procs, PidList} | TraceStartOption</v>
+ </type>
+ <desc>
+ <p>Calls <c>erlang:apply(Func, Args)</c> surrounded by
+ <c>trace([start, ...])</c> and
+ <c>trace(stop)</c>.
+ </p>
+ <p>Some effort is made to keep the trace clean from unnecessary
+ trace messages; tracing is started and stopped from a spawned
+ process while the <c>erlang:apply/2</c> call is made in the
+ current process, only surrounded by <c>receive</c> and
+ <c>send</c> statements towards the trace starting
+ process. The trace starting process exits when not needed
+ any more.
+ </p>
+ <p>The <c>TraceStartOption</c> is any option allowed for
+ <c>trace/1</c>. The options
+ <c>[start, {procs, [self() | PidList]} | OptList]</c>
+ are given to <c>trace/1</c>, where <c>OptList</c> is
+ <c>OptionList</c> with <c>continue</c>, <c>start</c>
+ and <c>{procs, _}</c> options removed.
+ </p>
+ <p>The <c>continue</c> option inhibits the call to
+ <c>trace(stop)</c> and leaves it up to the caller to stop
+ tracing at a suitable time.</p>
+ </desc>
+ </func>
+ <func>
+ <name>apply(Module, Function, Args, OptionList) -> term()</name>
+ <fsummary>Same as <c>apply({Module, Function}, Args, OptionList)</c>.</fsummary>
+ <type>
+ <v>Module = atom()</v>
+ <v>Function = atom()</v>
+ <v>Args = [term()]</v>
+ </type>
+ <desc>
+ <p>Same as
+ <c>apply({Module, Function}, Args, OptionList)</c>.
+ </p>
+ <p><c>OptionList</c> is an option list allowed for
+ <c>apply/3</c>.
+ <marker id="trace"></marker>
+</p>
+ </desc>
+ </func>
+ <func>
+ <name>trace(start, Filename) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>trace([start, {file, Filename}])</c>.</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as <c>trace([start, {file, Filename}])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>trace(verbose, Filename) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>trace([start, verbose, {file, Filename}])</c>.</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as
+ <c>trace([start, verbose, {file, Filename}])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>trace(OptionName, OptionValue) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>trace([{OptionName, OptionValue}])</c>.</fsummary>
+ <type>
+ <v>OptionName = atom()</v>
+ <v>OptionValue = term()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as
+ <c>trace([{OptionName, OptionValue}])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>trace(verbose) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>trace([start, verbose])</c>.</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as <c>trace([start, verbose])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>trace(OptionName) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>trace([OptionName])</c>.</fsummary>
+ <type>
+ <v>OptionName = atom()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as <c>trace([OptionName])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>trace({OptionName, OptionValue}) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>trace([{OptionName, OptionValue}])</c>.</fsummary>
+ <type>
+ <v>OptionName = atom()</v>
+ <v>OptionValue = term()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as
+ <c>trace([{OptionName, OptionValue}])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>trace([Option]) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Starts or stops tracing.</fsummary>
+ <type>
+ <v>Option = start | stop | {procs, PidSpec} | {procs, [PidSpec]} | verbose | {verbose, bool()} | file | {file, Filename} | {tracer, Tracer}</v>
+ <v>PidSpec = pid() | atom()</v>
+ <v>Tracer = pid() | port()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Starts or stops tracing.
+ </p>
+ <p><c>PidSpec</c> and <c>Tracer</c> are used in calls to
+ <c>erlang:trace(PidSpec, true, [{tracer, Tracer} | Flags])</c>, and <c>Filename</c> is used to call
+ <c>dbg:trace_port(file, Filename)</c>. Please see the
+ appropriate documentation.</p>
+ <p>Option description:</p>
+ <taglist>
+ <tag><c>stop</c></tag>
+ <item>Stops a running <c>fprof</c> trace and clears all tracing
+ from the node. Either option <c>stop</c> or <c>start</c> must be
+ specified, but not both.</item>
+ <tag><c>start</c></tag>
+ <item>Clears all tracing from the node and starts a new
+ <c>fprof</c> trace. Either option <c>start</c> or
+ <c>stop</c> must be specified, but not both.</item>
+ <tag><c>verbose</c>| <c>{verbose, bool()}</c></tag>
+ <item>The options <c>verbose</c> or <c>{verbose, true}</c>
+ adds some trace flags that <c>fprof</c> does not need, but
+ that may be interesting for general debugging
+ purposes. This option is only
+ allowed with the <c>start</c> option.</item>
+ <tag><c>cpu_time</c>| <c>{cpu_time, bool()}</c></tag>
+ <item>The options <c>cpu_time</c> or <c>{cpu_time, true></c>
+ makes the timestamps in the trace be in CPU time instead
+ of wallclock time which is the default. This option is
+ only allowed with the <c>start</c> option.</item>
+ <tag><c>{procs, PidSpec}</c>| <c>{procs, [PidSpec]}</c></tag>
+ <item>Specifies which processes that shall be traced. If
+ this option is not given, the calling process is
+ traced. All processes spawned by the traced processes are
+ also traced.
+ This option is only allowed with the <c>start</c> option.</item>
+ <tag><c>file</c>| <c>{file, Filename}</c></tag>
+ <item>Specifies the filename of the trace.
+ If the option <c>file</c> is given, or none of these
+ options are given, the file <c>"fprof.trace"</c> is used.
+ This option is only allowed with the <c>start</c> option,
+ but not with the <c>{tracer, Tracer}</c> option.</item>
+ <tag><c>{tracer, Tracer}</c></tag>
+ <item>Specifies that trace to process or port shall be done
+ instead of trace to file.
+ This option is only allowed with the <c>start</c> option,
+ but not with the <c>{file, Filename}</c> option.</item>
+ </taglist>
+ <marker id="profile"></marker>
+ </desc>
+ </func>
+ <func>
+ <name>profile() -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>profile([])</c>.</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as <c>profile([])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>profile(OptionName, OptionValue) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>profile([{OptionName, OptionValue}])</c>.</fsummary>
+ <type>
+ <v>OptionName = atom()</v>
+ <v>OptionValue = term()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as
+ <c>profile([{OptionName, OptionValue}])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>profile(OptionName) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>profile([OptionName])</c>.</fsummary>
+ <type>
+ <v>OptionName = atom()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as <c>profile([OptionName])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>profile({OptionName, OptionValue}) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>profile([{OptionName, OptionValue}])</c>.</fsummary>
+ <type>
+ <v>OptionName = atom()</v>
+ <v>OptionValue = term()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as
+ <c>profile([{OptionName, OptionValue}])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>profile([Option]) -> ok | {ok, Tracer} | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Compiles a trace into raw profile data held by the <c>fprof</c>&nbsp;server.</fsummary>
+ <type>
+ <v>Option = file | {file, Filename} | dump | {dump, Dump} | append | start | stop</v>
+ <v>Dump = pid() | Dumpfile | []</v>
+ <v>Tracer = pid()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Compiles a trace into raw profile data held by the
+ <c>fprof</c>&nbsp;server.
+ </p>
+ <p><c>Dumpfile</c> is used to call <c>file:open/2</c>,
+ and <c>Filename</c> is used to call
+ <c>dbg:trace_port(file, Filename)</c>. Please see the
+ appropriate documentation.</p>
+ <p>Option description:</p>
+ <taglist>
+ <tag><c>file</c>| <c>{file, Filename}</c></tag>
+ <item>Reads the file <c>Filename</c> and creates raw
+ profile data that is stored in RAM by the
+ <c>fprof</c>&nbsp;server. If the option <c>file</c> is
+ given, or none of these options are given, the file
+ <c>"fprof.trace"</c> is read. The call will return when
+ the whole trace has been
+ read with the return value <c>ok</c> if successful.
+ This option is not allowed with the <c>start</c> or
+ <c>stop</c> options.</item>
+ <tag><c>dump</c>| <c>{dump, Dump}</c></tag>
+ <item>Specifies the destination for the trace text dump. If
+ this option is not given, no dump is generated, if it is
+ <c>dump</c> the destination will be the
+ caller's group leader, otherwise the destination
+ <c>Dump</c> is either the pid of an I/O device or
+ a filename. And, finally, if the filename is <c>[]</c> -
+ <c>"fprof.dump"</c> is used instead.
+ This option is not allowed with the <c>stop</c> option.</item>
+ <tag><c>append</c></tag>
+ <item>Causes the trace text dump to be appended to the
+ destination file.
+ This option is only allowed with the
+ <c>{dump, Dumpfile}</c> option.</item>
+ <tag><c>start</c></tag>
+ <item>Starts a tracer process that profiles trace data in
+ runtime. The call will return immediately with the return
+ value <c>{ok, Tracer}</c> if successful.
+ This option is not allowed with the <c>stop</c>,
+ <c>file</c> or <c>{file, Filename}</c> options.</item>
+ <tag><c>stop</c></tag>
+ <item>Stops the tracer process that profiles trace data in
+ runtime. The return value will be value <c>ok</c> if successful.
+ This option is not allowed with the <c>start</c>,
+ <c>file</c> or <c>{file, Filename}</c> options.</item>
+ </taglist>
+ <marker id="analyse"></marker>
+ </desc>
+ </func>
+ <func>
+ <name>analyse() -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>analyse([])</c>.</fsummary>
+ <type>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as <c>analyse([])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>analyse(OptionName, OptionValue) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>analyse([{OptionName, OptionValue}])</c>.</fsummary>
+ <type>
+ <v>OptionName = atom()</v>
+ <v>OptionValue = term()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as
+ <c>analyse([{OptionName, OptionValue}])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>analyse(OptionName) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>analyse([OptionName])</c>.</fsummary>
+ <type>
+ <v>OptionName = atom()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as <c>analyse([OptionName])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>analyse({OptionName, OptionValue}) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Same as <c>analyse([{OptionName, OptionValue}])</c>.</fsummary>
+ <type>
+ <v>OptionName = atom()</v>
+ <v>OptionValue = term()</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Same as
+ <c>analyse([{OptionName, OptionValue}])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>analyse([Option]) -> ok | {error, Reason} | {'EXIT', ServerPid, Reason}</name>
+ <fsummary>Analyses raw profile data in the <c>fprof</c>&nbsp;server.</fsummary>
+ <type>
+ <v>Option = dest | {dest, Dest} | append | {cols, Cols} | callers | {callers, bool()} | no_callers | {sort, SortSpec} | totals | {totals, bool()} | details | {details, bool()} | no_details</v>
+ <v>Dest = pid() | Destfile</v>
+ <v>Cols = integer() >= 80</v>
+ <v>SortSpec = acc | own</v>
+ <v>Reason = term()</v>
+ </type>
+ <desc>
+ <p>Analyses raw profile data in the
+ <c>fprof</c>&nbsp;server. If called while there is no raw
+ profile data available, <c>{error, no_profile}</c> is
+ returned.
+ </p>
+ <p><c>Destfile</c> is used to call <c>file:open/2</c>.
+ Please see the appropriate documentation.</p>
+ <p>Option description:</p>
+ <taglist>
+ <tag><c>dest</c>| <c>{dest, Dest}</c></tag>
+ <item>Specifies the destination for the analysis. If
+ this option is not given or it is <c>dest</c>,
+ the destination will be the caller's group leader,
+ otherwise the destination <c>Dest</c> is either
+ the <c>pid()</c> of an I/O device or a filename.
+ And, finally, if the filename is <c>[]</c> -
+ <c>"fprof.analysis"</c> is used instead.</item>
+ <tag><c>append</c></tag>
+ <item>Causes the analysis to be appended to the
+ destination file.
+ This option is only allowed with the
+ <c>{dest, Destfile}</c> option.</item>
+ <tag><c>{cols, Cols}</c></tag>
+ <item>Specifies the number of columns in the analysis text.
+ If this option is not given the number of columns is set
+ to 80.</item>
+ <tag><c>callers</c>| <c>{callers, true}</c></tag>
+ <item>Prints callers and called information in the
+ analysis. This is the default.</item>
+ <tag><c>{callers, false}</c>| <c>no_callers</c></tag>
+ <item>Suppresses the printing of callers and called
+ information in the analysis.</item>
+ <tag><c>{sort, SortSpec}</c></tag>
+ <item>Specifies if the analysis should be sorted according
+ to the ACC column, which is the default, or the OWN
+ column. See
+ <seealso marker="#analysis">Analysis Format</seealso> below.</item>
+ <tag><c>totals</c>| <c>{totals, true}</c></tag>
+ <item>Includes a section containing call statistics
+ for all calls regardless of process, in the analysis.</item>
+ <tag><c>{totals, false}</c></tag>
+ <item>Supresses the totals section in the analysis, which is
+ the default.</item>
+ <tag><c>details</c>| <c>{details, true}</c></tag>
+ <item>Prints call statistics for each process in the
+ analysis. This is the default.</item>
+ <tag><c>{details, false}</c>| <c>no_details</c></tag>
+ <item>Suppresses the call statistics for each process from
+ the analysis.</item>
+ </taglist>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <marker id="analysis"></marker>
+ <title>Analysis format</title>
+ <p>This section describes the output format of the analyse
+ command. See <seealso marker="#analyse">analyse/0</seealso>.
+ </p>
+ <p>The format is parsable with the standard Erlang parsing tools
+ <c>erl_scan</c> and <c>erl_parse</c>, <c>file:consult/1</c> or
+ <c>io:read/2</c>. The parse format is not explained here - it
+ should be easy for the interested to try it out. Note that some
+ flags to <c>analyse/1</c> will affect the format.
+ </p>
+ <p>The following example was run on OTP/R8 on Solaris 8, all OTP
+ internals in this example are very version dependent.
+ </p>
+ <p>As an example, we will use the following function, that you may
+ recognise as a slightly modified benchmark function from the
+ manpage file(3):</p>
+ <code type="none"><![CDATA[
+-module(foo).
+-export([create_file_slow/2]).
+
+create_file_slow(Name, N) when integer(N), N >= 0 ->
+ {ok, FD} =
+ file:open(Name, [raw, write, delayed_write, binary]),
+ if N > 256 ->
+ ok = file:write(FD,
+ lists:map(fun (X) -> <<X:32/unsigned>> end,
+ lists:seq(0, 255))),
+ ok = create_file_slow(FD, 256, N);
+ true ->
+ ok = create_file_slow(FD, 0, N)
+ end,
+ ok = file:close(FD).
+
+create_file_slow(FD, M, M) ->
+ ok;
+create_file_slow(FD, M, N) ->
+ ok = file:write(FD, <<M:32/unsigned>>),
+ create_file_slow(FD, M+1, N).]]></code>
+ <p>Let us have a look at the printout after running:</p>
+ <pre>
+1> <input>fprof:apply(foo, create_file_slow, [junk, 1024]).</input>
+2> <input>fprof:profile().</input>
+3> <input>fprof:analyse().</input></pre>
+ <p>The printout starts with:</p>
+ <pre>
+%% Analysis results:
+{ analysis_options,
+ [{callers, true},
+ {sort, acc},
+ {totals, false},
+ {details, true}]}.
+
+% CNT ACC OWN
+[{ totals, 9627, 1691.119, 1659.074}]. %%%</pre>
+ <p>The CNT column shows the total number of function calls that
+ was found in the trace. In the ACC column is the total time of
+ the trace from first timestamp to last. And in the OWN
+ column is the sum of the execution time in functions found in the
+ trace, not including called functions. In this case it is very
+ close to the ACC time since the emulator had practically nothing
+ else to do than to execute our test program.
+ </p>
+ <p>All time values in the printout are in milliseconds.
+ </p>
+ <p>The printout continues:</p>
+ <pre>
+% CNT ACC OWN
+[{ "&lt;0.28.0>", 9627,undefined, 1659.074}]. %%</pre>
+ <p>This is the printout header of one process. The printout
+ contains only this one process since we did <c>fprof:apply/3</c>
+ which traces only the current process. Therefore the CNT and
+ OWN columns perfectly matches the totals above. The ACC column is
+ undefined since summing the ACC times of all calls in the process
+ makes no sense - you would get something like the ACC value from
+ totals above multiplied by the average depth of the call stack,
+ or something.
+ </p>
+ <p>All paragraphs up to the next process header only concerns
+ function calls within this process.
+ </p>
+ <p>Now we come to something more interesting:</p>
+ <pre>
+{[{undefined, 0, 1691.076, 0.030}],
+ { {fprof,apply_start_stop,4}, 0, 1691.076, 0.030}, %
+ [{{foo,create_file_slow,2}, 1, 1691.046, 0.103},
+ {suspend, 1, 0.000, 0.000}]}.
+
+{[{{fprof,apply_start_stop,4}, 1, 1691.046, 0.103}],
+ { {foo,create_file_slow,2}, 1, 1691.046, 0.103}, %
+ [{{file,close,1}, 1, 1398.873, 0.019},
+ {{foo,create_file_slow,3}, 1, 249.678, 0.029},
+ {{file,open,2}, 1, 20.778, 0.055},
+ {{lists,map,2}, 1, 16.590, 0.043},
+ {{lists,seq,2}, 1, 4.708, 0.017},
+ {{file,write,2}, 1, 0.316, 0.021}]}. </pre>
+ <p>The printout consists of one paragraph per called function. The
+ function <em>marked</em> with '%' is the one the paragraph
+ concerns - <c>foo:create_file_slow/2</c>. Above the marked
+ function are the <em>calling</em> functions - those that has
+ called the marked, and below are those <em>called</em> by the
+ marked function.
+ </p>
+ <p>The paragraphs are per default sorted in decreasing order of
+ the ACC column for the marked function. The calling list and
+ called list within one paragraph are also per default sorted in
+ decreasing order of their ACC column.
+ </p>
+ <p>The columns are: CNT - the number of times the function
+ has been called, ACC - the time spent in the
+ function including called functions, and OWN - the
+ time spent in the function not including called
+ functions.
+ </p>
+ <p>The rows for the <em>calling</em> functions contain statistics
+ for the <em>marked</em> function with the constraint that only
+ the occasions when a call was made from the <em>row's</em>
+ function to the <em>marked</em> function are accounted for.
+ </p>
+ <p>The row for the <em>marked</em> function simply contains the
+ sum of all <em>calling</em> rows.
+ </p>
+ <p>The rows for the <em>called</em> functions contains statistics
+ for the <em>row's</em> function with the constraint that only the
+ occasions when a call was made from the <em>marked</em> to the
+ <em>row's</em> function are accounted for.
+ </p>
+ <p>So, we see that <c>foo:create_file_slow/2</c> used very little
+ time for its own execution. It spent most of its time in
+ <c>file:close/1</c>. The function <c>foo:create_file_slow/3</c>
+ that writes 3/4 of the file contents is the second biggest time
+ thief.
+ </p>
+ <p>We also see that the call to <c>file:write/2</c> that writes
+ 1/4 of the file contents takes very little time in itself. What
+ takes time is to build the data (<c>lists:seq/2</c> and
+ <c>lists:map/2</c>).
+ </p>
+ <p>The function 'undefined' that has called
+ <c>fprof:apply_start_stop/4</c> is an unknown function because that
+ call was not recorded in the trace. It was only recorded
+ that the execution returned from
+ <c>fprof:apply_start_stop/4</c> to some other function above in
+ the call stack, or that the process exited from there.
+ </p>
+ <p>Let us continue down the printout to find:</p>
+ <pre>
+{[{{foo,create_file_slow,2}, 1, 249.678, 0.029},
+ {{foo,create_file_slow,3}, 768, 0.000, 23.294}],
+ { {foo,create_file_slow,3}, 769, 249.678, 23.323}, %
+ [{{file,write,2}, 768, 220.314, 14.539},
+ {suspend, 57, 6.041, 0.000},
+ {{foo,create_file_slow,3}, 768, 0.000, 23.294}]}. </pre>
+ <p>If you compare with the code you will see there also that
+ <c>foo:create_file_slow/3</c> was called only from
+ <c>foo:create_file_slow/2</c> and itself, and called only
+ <c>file:write/2</c>, note the number of calls to
+ <c>file:write/2</c>. But here we see that <c>suspend</c> was
+ called a few times. This is a pseudo function that indicates
+ that the process was suspended while executing in
+ <c>foo:create_file_slow/3</c>, and since there is no
+ <c>receive</c> or <c>erlang:yield/0</c> in the code, it must be
+ Erlang scheduling suspensions, or the trace file driver
+ compensating for large file write operations (these are regarded
+ as a schedule out followed by a schedule in to the same process).
+ </p>
+ <p></p>
+ <p>Let us find the <c>suspend</c> entry:</p>
+ <pre>
+{[{{file,write,2}, 53, 6.281, 0.000},
+ {{foo,create_file_slow,3}, 57, 6.041, 0.000},
+ {{prim_file,drv_command,4}, 50, 4.582, 0.000},
+ {{prim_file,drv_get_response,1}, 34, 2.986, 0.000},
+ {{lists,map,2}, 10, 2.104, 0.000},
+ {{prim_file,write,2}, 17, 1.852, 0.000},
+ {{erlang,port_command,2}, 15, 1.713, 0.000},
+ {{prim_file,drv_command,2}, 22, 1.482, 0.000},
+ {{prim_file,translate_response,2}, 11, 1.441, 0.000},
+ {{prim_file,'-drv_command/2-fun-0-',1}, 15, 1.340, 0.000},
+ {{lists,seq,4}, 3, 0.880, 0.000},
+ {{foo,'-create_file_slow/2-fun-0-',1}, 5, 0.523, 0.000},
+ {{erlang,bump_reductions,1}, 4, 0.503, 0.000},
+ {{prim_file,open_int_setopts,3}, 1, 0.165, 0.000},
+ {{prim_file,i32,4}, 1, 0.109, 0.000},
+ {{fprof,apply_start_stop,4}, 1, 0.000, 0.000}],
+ { suspend, 299, 32.002, 0.000}, %
+ [ ]}.</pre>
+ <p>We find no particulary long suspend times, so no function seems
+ to have waited in a receive statement. Actually,
+ <c>prim_file:drv_command/4</c> contains a receive statement, but
+ in this test program, the message lies in the process receive
+ buffer when the receive statement is entered. We also see that
+ the total suspend time for the test run is small.
+ </p>
+ <p>The <c>suspend</c> pseudo function has got an OWN time of
+ zero. This is to prevent the process total OWN time from
+ including time in suspension. Whether suspend time is really ACC
+ or OWN time is more of a philosophical question.
+ </p>
+ <p>Now we look at another interesting pseudo function,
+ <c>garbage_collect</c>:</p>
+ <pre>
+{[{{prim_file,drv_command,4}, 25, 0.873, 0.873},
+ {{prim_file,write,2}, 16, 0.692, 0.692},
+ {{lists,map,2}, 2, 0.195, 0.195}],
+ { garbage_collect, 43, 1.760, 1.760}, %
+ [ ]}.</pre>
+ <p>Here we see that no function distinguishes itself considerably,
+ which is very normal.
+ </p>
+ <p>The <c>garbage_collect</c> pseudo function has not got an OWN
+ time of zero like <c>suspend</c>, instead it is equal to the ACC
+ time.
+ </p>
+ <p>Garbage collect often occurs while a process is suspended, but
+ <c>fprof</c> hides this fact by pretending that the suspended
+ function was first unsuspended and then garbage
+ collected. Otherwise the printout would show
+ <c>garbage_collect</c> being called from <c>suspend</c> but not
+ not which function that might have caused the garbage
+ collection.
+ </p>
+ <p>Let us now get back to the test code:</p>
+ <pre>
+{[{{foo,create_file_slow,3}, 768, 220.314, 14.539},
+ {{foo,create_file_slow,2}, 1, 0.316, 0.021}],
+ { {file,write,2}, 769, 220.630, 14.560}, %
+ [{{prim_file,write,2}, 769, 199.789, 22.573},
+ {suspend, 53, 6.281, 0.000}]}. </pre>
+ <p>Not unexpectedly, we see that <c>file:write/2</c> was called
+ from <c>foo:create_file_slow/3</c> and
+ <c>foo:create_file_slow/2</c>. The number of calls in each case as
+ well as the used time are also just confirms the previous results.
+ </p>
+ <p>We see that <c>file:write/2</c> only calls
+ <c>prim_file:write/2</c>, but let us refrain from digging into the
+ internals of the kernel application.
+ </p>
+ <p>But, if we nevertheless <em>do</em> dig down we find
+ the call to the linked in driver that does the file operations
+ towards the host operating system:</p>
+ <pre>
+{[{{prim_file,drv_command,4}, 772, 1458.356, 1456.643}],
+ { {erlang,port_command,2}, 772, 1458.356, 1456.643}, %
+ [{suspend, 15, 1.713, 0.000}]}. </pre>
+ <p>This is 86 % of the total run time, and as we saw before it
+ is the close operation the absolutely biggest contributor. We
+ find a comparison ratio a little bit up in the call stack:</p>
+ <pre>
+{[{{prim_file,close,1}, 1, 1398.748, 0.024},
+ {{prim_file,write,2}, 769, 174.672, 12.810},
+ {{prim_file,open_int,4}, 1, 19.755, 0.017},
+ {{prim_file,open_int_setopts,3}, 1, 0.147, 0.016}],
+ { {prim_file,drv_command,2}, 772, 1593.322, 12.867}, %
+ [{{prim_file,drv_command,4}, 772, 1578.973, 27.265},
+ {suspend, 22, 1.482, 0.000}]}. </pre>
+ <p>The time for file operations in the linked in driver
+ distributes itself as 1 % for open, 11 % for write and 87 % for
+ close. All data is probably buffered in the operating system
+ until the close.
+ </p>
+ <p>The unsleeping reader may notice that the ACC times for
+ <c>prim_file:drv_command/2</c> and
+ <c>prim_file:drv_command/4</c> is not equal between the
+ paragraphs above, even though it is easy to believe that
+ <c>prim_file:drv_command/2</c> is just a passthrough function.
+ </p>
+ <p>The missing time can be found in the paragraph
+ for <c>prim_file:drv_command/4</c> where it is evident that not
+ only <c>prim_file:drv_command/2</c> is called but also a fun:
+ </p>
+ <pre>
+{[{{prim_file,drv_command,2}, 772, 1578.973, 27.265}],
+ { {prim_file,drv_command,4}, 772, 1578.973, 27.265}, %
+ [{{erlang,port_command,2}, 772, 1458.356, 1456.643},
+ {{prim_file,'-drv_command/2-fun-0-',1}, 772, 87.897, 12.736},
+ {suspend, 50, 4.582, 0.000},
+ {garbage_collect, 25, 0.873, 0.873}]}. </pre>
+ <p>And some more missing time can be explained by the fact that
+ <c>prim_file:open_int/4</c> both calls
+ <c>prim_file:drv_command/2</c> directly as well as through
+ <c>prim_file:open_int_setopts/3</c>, which complicates the
+ picture.
+ </p>
+ <pre>
+{[{{prim_file,open,2}, 1, 20.309, 0.029},
+ {{prim_file,open_int,4}, 1, 0.000, 0.057}],
+ { {prim_file,open_int,4}, 2, 20.309, 0.086}, %
+ [{{prim_file,drv_command,2}, 1, 19.755, 0.017},
+ {{prim_file,open_int_setopts,3}, 1, 0.360, 0.032},
+ {{prim_file,drv_open,2}, 1, 0.071, 0.030},
+ {{erlang,list_to_binary,1}, 1, 0.020, 0.020},
+ {{prim_file,i32,1}, 1, 0.017, 0.017},
+ {{prim_file,open_int,4}, 1, 0.000, 0.057}]}.
+.
+.
+.
+{[{{prim_file,open_int,4}, 1, 0.360, 0.032},
+ {{prim_file,open_int_setopts,3}, 1, 0.000, 0.016}],
+ { {prim_file,open_int_setopts,3}, 2, 0.360, 0.048}, %
+ [{suspend, 1, 0.165, 0.000},
+ {{prim_file,drv_command,2}, 1, 0.147, 0.016},
+ {{prim_file,open_int_setopts,3}, 1, 0.000, 0.016}]}. </pre>
+ </section>
+
+ <section>
+ <title>Notes</title>
+ <p>The actual supervision of execution times is in itself a
+ CPU intensive activity. A message is written on the trace file
+ for every function call that is made by the profiled code.
+ </p>
+ <p>The ACC time calculation is sometimes difficult to make
+ correct, since it is difficult to define. This happens
+ especially when a function occurs in several instances in the
+ call stack, for example by calling itself perhaps through other
+ functions and perhaps even non-tail recursively.
+ </p>
+ <p>To produce sensible results, <c>fprof</c> tries not to charge
+ any function more than once for ACC time. The instance highest
+ up (with longest duration) in the call stack is chosen.
+ </p>
+ <p>Sometimes a function may unexpectedly waste a lot (some 10 ms
+ or more depending on host machine OS) of OWN (and ACC) time, even
+ functions that does practically nothing at all. The problem may
+ be that the OS has chosen to schedule out the
+ Erlang runtime system process for a while, and if the OS does
+ not support high resolution cpu time measurements
+ <c>fprof</c> will use wallclock time for its calculations, and
+ it will appear as functions randomly burn virtual machine time.</p>
+ </section>
+
+ <section>
+ <title>See Also</title>
+ <p>dbg(3), <seealso marker="eprof">eprof</seealso>(3), erlang(3),
+ io(3),
+ <seealso marker="fprof_chapter">Tools User's Guide</seealso></p>
+ </section>
+</erlref>
+
diff --git a/lib/tools/doc/src/fprof_chapter.xml b/lib/tools/doc/src/fprof_chapter.xml
new file mode 100644
index 0000000000..3f40d93f40
--- /dev/null
+++ b/lib/tools/doc/src/fprof_chapter.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2001</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>fprof - The File Trace Profiler</title>
+ <prepared>Raimo Niskanen</prepared>
+ <responsible>nobody</responsible>
+ <docno></docno>
+ <approved>nobody</approved>
+ <checked>no</checked>
+ <date>2001-08-14</date>
+ <rev>PA1</rev>
+ <file>fprof_chapter.xml</file>
+ </header>
+ <p><c>fprof</c> is a profiling tool that can be used to get a picture of
+ how much processing time different functions consumes and in which
+ processes.
+ </p>
+ <p><c>fprof</c> uses tracing with timestamps to collect profiling
+ data. Therfore there is no need for special compilation of any
+ module to be profiled.
+ </p>
+ <p><c>fprof</c> presents wall clock times from the host machine OS,
+ with the assumption that OS scheduling will randomly load the
+ profiled functions in a fair way. Both <em>own time</em> i.e the
+ time used by a function for its own execution, and
+ <em>accumulated time</em> i.e execution time including called
+ functions.
+ </p>
+ <p>Profiling is essentially done in 3 steps:</p>
+ <taglist>
+ <tag><c>1</c></tag>
+ <item>Tracing; to file, as mentioned in the previous paragraph.</item>
+ <tag><c>2</c></tag>
+ <item>Profiling; the trace file is read and raw profile data is
+ collected into an internal RAM storage on the node. During
+ this step the trace data may be dumped in text format to file
+ or console.</item>
+ <tag><c>3</c></tag>
+ <item>Analysing; the raw profile data is sorted and dumped
+ in text format either to file or console.</item>
+ </taglist>
+ <p>Since <c>fprof</c> uses trace to file, the runtime performance
+ degradation is minimized, but still far from negligible,
+ especially not for programs that use the filesystem heavily
+ by themselves. Where you place the trace file is also important,
+ e.g on Solaris <c>/tmp</c> is usually a good choice,
+ while any NFS mounted disk is a lousy choice.
+ </p>
+ <p>Fprof can also skip the file step and trace to a tracer process
+ of its own that does the profiling in runtime.
+ </p>
+ <p>The following sections show some examples of how to profile with
+ Fprof. See also the reference manual
+ <seealso marker="fprof">fprof(3)</seealso>.
+ </p>
+
+ <section>
+ <title>Profiling from the source code</title>
+ <p>If you can edit and recompile the source code, it is convenient
+ to insert <c>fprof:trace(start)</c> and
+ <c>fprof:trace(stop)</c> before and after the code to be
+ profiled. All spawned processes are also traced. If you want
+ some other filename than the default try
+ <c>fprof:trace(start, "my_fprof.trace")</c>.
+ </p>
+ <p>Then read the trace file and create the raw profile data with
+ <c>fprof:profile()</c>, or perhaps
+ <c>fprof:profile(file, "my_fprof.trace")</c> for non-default
+ filename.
+ </p>
+ <p>Finally create an informative table dumped on the console with
+ <c>fprof:analyse()</c>, or on file with
+ <c>fprof:analyse(dest, [])</c>, or perhaps even
+ <c>fprof:analyse([{dest, "my_fprof.analysis"}, {cols, 120}])</c>
+ for a wider listing on non-default filename.
+ </p>
+ <p>See the <seealso marker="fprof">fprof(3)</seealso> manual page
+ for more options and arguments to the functions
+ <seealso marker="fprof#trace">trace</seealso>,
+ <seealso marker="fprof#profile">profile</seealso>
+ and
+ <seealso marker="fprof#analyse">analyse</seealso>.
+ </p>
+ </section>
+
+ <section>
+ <title>Profiling a function</title>
+ <p>If you have one function that does the task that you want to
+ profile, and the function returns when the profiling should
+ stop, it is convenient to use
+ <c>fprof:apply(Module, Function, Args)</c> and related for the
+ tracing step.
+ </p>
+ <p>If the tracing should continue after the function returns, for
+ example if it is a start function that spawns processes to be
+ profiled, you can use
+ <c>fprof:apply(M, F, Args, [continue | OtherOpts])</c>.
+ The tracing has to be stopped at a suitable later time using
+ <c>fprof:trace(stop)</c>.
+ </p>
+ </section>
+
+ <section>
+ <title>Immediate profiling</title>
+ <p>It is also possible to trace immediately into the profiling
+ process that creates the raw profile data, that is to short
+ circuit the tracing and profiling steps so that the filesystem
+ is not used.
+ </p>
+ <p>Do something like this:</p>
+ <pre>
+{ok, Tracer} = fprof:profile(start),
+fprof:trace([start, {tracer, Tracer}]),
+%% Code to profile
+fprof:trace(stop);</pre>
+ <p>This puts less load on the filesystem, but much more on the
+ Erlang runtime system.
+ </p>
+ </section>
+</chapter>
+
diff --git a/lib/tools/doc/src/instrument.xml b/lib/tools/doc/src/instrument.xml
new file mode 100644
index 0000000000..12877994de
--- /dev/null
+++ b/lib/tools/doc/src/instrument.xml
@@ -0,0 +1,432 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>1998</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>instrument</title>
+ <prepared>Arndt Jonasson</prepared>
+ <responsible>Torbj&ouml;rn Johnsson</responsible>
+ <docno>1</docno>
+ <approved>Bj&ouml;rn Gustavsson</approved>
+ <checked></checked>
+ <date>98-04-01</date>
+ <rev>PA1</rev>
+ <file>instrument.sgml</file>
+ </header>
+ <module>instrument</module>
+ <modulesummary>Analysis and Utility Functions for Instrumentation</modulesummary>
+ <description>
+ <p>The module <c>instrument</c> contains support for studying the resource
+ usage in an Erlang runtime system. Currently, only the allocation of memory can
+ be studied.</p>
+ <note>
+ <p>Note that this whole module is experimental, and the representations
+ used as well as the functionality is likely to change in the future.</p>
+ <p>The <c>instrument</c> module interface was slightly changed in
+ Erlang/OTP R9C.</p>
+ </note>
+ <p>To start an Erlang runtime system with instrumentation, use the
+ <c>+Mi*</c> set of command-line arguments to the <c>erl</c> command (see
+ the erts_alloc(3) and erl(1) man pages).</p>
+ <p>The basic object of study in the case of memory allocation is a memory
+ allocation map. A memory allocation map contains a list of descriptors
+ for each allocated memory block. Currently, a descriptor is a 4-tuple</p>
+ <pre>
+ {TypeNo, Address, Size, PidDesc} </pre>
+ <p>where <c>TypeNo</c> is the memory block type number, <c>Address</c>
+ is its place in memory, and <c>Size</c> is its size, in bytes.
+ <c>PidDesc</c> is either a tuple <c>{X,Y,Z}</c> identifying the
+ process which was executing when the block was allocated, or
+ <c>undefined</c> if no process was executing. The pid tuple
+ <c>{X,Y,Z}</c> can be transformed into a real pid by usage of the
+ <c>c:pid/3</c> function.</p>
+ <p>Various details about memory allocation:</p>
+ <p>Memory blocks are allocated both on the heap segment and on other memory
+ segments. This can cause the instrumentation functionality to report
+ very large holes. Currently the instrumentation functionality doesn't
+ provide any support for distinguishing between holes between memory
+ segments, and holes between allocated blocks inside memory segments.
+ The current size of the process cannot be obtained from within Erlang,
+ but can be seen with one of the system statistics tools, e.g.,
+ <c>ps</c> or <c>top</c>. The Solaris utility <c>pmap</c> can be
+ useful. It reports currently mapped memory segments. </p>
+ <p>Overhead for instrumentation: When the emulator has been started with
+ the <seealso marker="erts:erts_alloc#Mim">"+Mim true"</seealso>
+ flag, each block is preceded by a 24 bytes large
+ header on a 32-bit machine and a 48 bytes large header on a 64-bit
+ machine. When the emulator has been started with the
+ <seealso marker="erts:erts_alloc#Mis">"+Mis true"</seealso>
+ flag, each block is preceded by an 8 bytes large header. These are the header
+ sizes used by the Erlang 5.3/OTP R9C emulator. Other versions of the
+ emulator may use other header sizes. The function
+ <seealso marker="#block_header_size/1">block_header_size/1</seealso>
+ can be used for retrieving the header size used for a specific memory
+ allocation map. The time overhead for managing the instrumentation
+ data is small.</p>
+ <p>Sizes presented by the instrumentation functionality are (by the
+ emulator) requested sizes, i.e. neither instrumentation headers nor
+ headers used by allocators are included.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>allocator_descr(MemoryData, TypeNo) -> AllocDescr | invalid_type | "unknown"</name>
+ <fsummary>Returns a allocator description</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>TypeNo = int()</v>
+ <v>AllocDescr = atom() | string()</v>
+ </type>
+ <desc>
+ <p>Returns the allocator description of the allocator that
+ manages memory blocks of type number <c>TypeNo</c> used in
+ <c>MemoryData</c>.
+ Valid <c>TypeNo</c>s are in the range returned by
+ <seealso marker="#type_no_range/1">type_no_range/1</seealso> on
+ this specific memory allocation map. If <c>TypeNo</c> is an
+ invalid integer, <c>invalid_type</c> is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>block_header_size(MemoryData) -> int()</name>
+ <fsummary>Returns the memory block header size used by the emulator that generated the memory allocation map</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <marker id="block_header_size_1"></marker>
+ <p>Returns the memory block header size used by the
+ emulator that generated the memory allocation map. The block
+ header size may differ between different emulators.</p>
+ </desc>
+ </func>
+ <func>
+ <name>class_descr(MemoryData, TypeNo) -> ClassDescr | invalid_type | "unknown"</name>
+ <fsummary>Returns a allocator description</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>TypeNo = int()</v>
+ <v>ClassDescr = atom() | string()</v>
+ </type>
+ <desc>
+ <p>Returns the class description of the class that
+ the type number <c>TypeNo</c> used in <c>MemoryData</c> belongs
+ to.
+ Valid <c>TypeNo</c>s are in the range returned by
+ <seealso marker="#type_no_range/1">type_no_range/1</seealso> on
+ this specific memory allocation map. If <c>TypeNo</c> is an
+ invalid integer, <c>invalid_type</c> is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>descr(MemoryData) -> DescrMemoryData</name>
+ <fsummary>Replace type numbers in memory allocation map with type descriptions</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>DescrMemoryData = {term(), DescrAllocList}</v>
+ <v>DescrAllocList = [DescrDesc]</v>
+ <v>DescrDesc = {TypeDescr, int(), int(), DescrPidDesc}</v>
+ <v>TypeDescr = atom() | string()</v>
+ <v>DescrPidDesc = pid() | undefined</v>
+ </type>
+ <desc>
+ <p>Returns a memory allocation map where the type numbers (first
+ element of <c>Desc</c>) have been replaced by type descriptions,
+ and pid tuples (fourth element of <c>Desc</c>) have been
+ replaced by real pids.</p>
+ </desc>
+ </func>
+ <func>
+ <name>holes(MemoryData) -> ok</name>
+ <fsummary>Print out the sizes of unused memory blocks</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <p>Prints out the size of each hole (i.e., the space between
+ allocated blocks) on the terminal. <em>NOTE:</em> Really large holes
+ are probably holes between memory segments.
+ The memory allocation map has to be sorted (see
+ <seealso marker="#sort/1">sort/1</seealso>).</p>
+ </desc>
+ </func>
+ <func>
+ <name>mem_limits(MemoryData) -> {Low, High}</name>
+ <fsummary>Return lowest and highest memory address used</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>Low = High = int()</v>
+ </type>
+ <desc>
+ <p>Returns a tuple <c>{Low, High}</c> indicating
+ the lowest and highest address used.
+ The memory allocation map has to be sorted (see
+ <seealso marker="#sort/1">sort/1</seealso>).</p>
+ </desc>
+ </func>
+ <func>
+ <name>memory_data() -> MemoryData | false</name>
+ <fsummary>Return the current memory allocation map</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <p>Returns <c>MemoryData</c> (a the memory allocation map)
+ if the emulator has been started with the "<c>+Mim true</c>"
+ command-line argument; otherwise, <c>false</c>. <em>NOTE:</em><c>memory_data/0</c> blocks execution of other processes while
+ the data is collected. The time it takes to collect the data can
+ be substantial.</p>
+ </desc>
+ </func>
+ <func>
+ <name>memory_status(StatusType) -> [StatusInfo] | false</name>
+ <fsummary>Return current memory allocation status</fsummary>
+ <type>
+ <v>StatusType = total | allocators | classes | types</v>
+ <v>StatusInfo = {About, [Info]}</v>
+ <v>About = atom()</v>
+ <v>Info = {InfoName, Current, MaxSinceLast, MaxEver}</v>
+ <v>InfoName = sizes|blocks</v>
+ <v>Current = int()</v>
+ <v>MaxSinceLast = int()</v>
+ <v>MaxEver = int()</v>
+ </type>
+ <desc>
+ <p>Returns a list of <c>StatusInfo</c> if the emulator has been
+ started with the "<c>+Mis true</c>" or "<c>+Mim true</c>"
+ command-line argument; otherwise, <c>false</c>. </p>
+ <p>See the
+ <seealso marker="#read_memory_status/1">read_memory_status/1</seealso>
+ function for a description of the <c>StatusInfo</c> term.</p>
+ </desc>
+ </func>
+ <func>
+ <name>read_memory_data(File) -> MemoryData | {error, Reason}</name>
+ <fsummary>Read memory allocation map</fsummary>
+ <type>
+ <v>File = string()</v>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <marker id="read_memory_data_1"></marker>
+ <p>Reads a memory allocation map from the file <c>File</c> and
+ returns it. The file is assumed to have been created by
+ <c>store_memory_data/1</c>. The error codes are the same as for
+ <c>file:consult/1</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>read_memory_status(File) -> MemoryStatus | {error, Reason}</name>
+ <fsummary>Read memory allocation status from a file</fsummary>
+ <type>
+ <v>File = string()</v>
+ <v>MemoryStatus = [{StatusType, [StatusInfo]}]</v>
+ <v>StatusType = total | allocators | classes | types</v>
+ <v>StatusInfo = {About, [Info]}</v>
+ <v>About = atom()</v>
+ <v>Info = {InfoName, Current, MaxSinceLast, MaxEver}</v>
+ <v>InfoName = sizes|blocks</v>
+ <v>Current = int()</v>
+ <v>MaxSinceLast = int()</v>
+ <v>MaxEver = int()</v>
+ </type>
+ <desc>
+ <marker id="read_memory_status_1"></marker>
+ <p>Reads memory allocation status from the file <c>File</c> and
+ returns it. The file is assumed to have been created by
+ <c>store_memory_status/1</c>. The error codes are the same as
+ for <c>file:consult/1</c>.</p>
+ <p>When <c>StatusType</c> is <c>allocators</c>, <c>About</c> is
+ the allocator that the information is about. When
+ <c>StatusType</c> is <c>types</c>, <c>About</c> is
+ the memory block type that the information is about. Memory
+ block types are not described other than by their name and may
+ vary between emulators. When <c>StatusType</c> is <c>classes</c>,
+ <c>About</c> is the memory block type class that information is
+ presented about. Memory block types are classified after their
+ use. Currently the following classes exist:</p>
+ <taglist>
+ <tag><c>process_data</c></tag>
+ <item>Erlang process specific data.</item>
+ <tag><c>binary_data</c></tag>
+ <item>Erlang binaries.</item>
+ <tag><c>atom_data</c></tag>
+ <item>Erlang atoms.</item>
+ <tag><c>code_data</c></tag>
+ <item>Erlang code.</item>
+ <tag><c>system_data</c></tag>
+ <item>Other data used by the system</item>
+ </taglist>
+ <p>When <c>InfoName</c> is <c>sizes</c>, <c>Current</c>,
+ <c>MaxSinceLast</c>, and <c>MaxEver</c> are, respectively, current
+ size, maximum size since last call to
+ <c>store_memory_status/1</c> or <c>memory_status/1</c> with the
+ specific <c>StatusType</c>, and maximum size since the emulator
+ was started. When <c>InfoName</c> is <c>blocks</c>, <c>Current</c>,
+ <c>MaxSinceLast</c>, and <c>MaxEver</c> are, respectively, current
+ number of blocks, maximum number of blocks since last call to
+ <c>store_memory_status/1</c> or <c>memory_status/1</c> with the
+ specific <c>StatusType</c>, and maximum number of blocks since the
+ emulator was started. </p>
+ <p><em>NOTE:</em>A memory block is accounted for at
+ "the first level" allocator. E.g. <c>fix_alloc</c> allocates its
+ memory pools via <c>ll_alloc</c>. When a <c>fix_alloc</c> block
+ is allocated, neither the block nor the pool in which it resides
+ are accounted for as memory allocated via <c>ll_alloc</c> even
+ though it is.</p>
+ </desc>
+ </func>
+ <func>
+ <name>sort(MemoryData) -> MemoryData</name>
+ <fsummary>Sort the memory allocation list</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <marker id="sort_1"></marker>
+ <p>Sorts a memory allocation map so that the addresses are in
+ ascending order.</p>
+ </desc>
+ </func>
+ <func>
+ <name>store_memory_data(File) -> true|false</name>
+ <fsummary>Store the current memory allocation map on a file</fsummary>
+ <type>
+ <v>File = string()</v>
+ </type>
+ <desc>
+ <p>Stores the current memory allocation map on the file
+ <c>File</c>. Returns <c>true</c> if the emulator has been
+ started with the "<c>+Mim true</c>" command-line argument, and
+ the map was successfuly stored; otherwise, <c>false</c>. The
+ contents of the file can later be read using
+ <seealso marker="#read_memory_data/1">read_memory_data/1</seealso>.
+ <em>NOTE:</em><c>store_memory_data/0</c> blocks execution of
+ other processes while the data is collected. The time it takes
+ to collect the data can be substantial.</p>
+ </desc>
+ </func>
+ <func>
+ <name>store_memory_status(File) -> true|false</name>
+ <fsummary>Store the current memory allocation status on a file</fsummary>
+ <type>
+ <v>File = string()</v>
+ </type>
+ <desc>
+ <p>Stores the current memory status on the file
+ <c>File</c>. Returns <c>true</c> if the emulator has been
+ started with the "<c>+Mis true</c>", or "<c>+Mim true</c>"
+ command-line arguments, and the data was successfuly stored;
+ otherwise, <c>false</c>. The contents of the file can later be
+ read using
+ <seealso marker="#read_memory_status/1">read_memory_status/1</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>sum_blocks(MemoryData) -> int()</name>
+ <fsummary>Return the total amount of memory used</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ </type>
+ <desc>
+ <p>Returns the total size of the memory blocks in the list.</p>
+ </desc>
+ </func>
+ <func>
+ <name>type_descr(MemoryData, TypeNo) -> TypeDescr | invalid_type</name>
+ <fsummary>Returns a type description</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>TypeNo = int()</v>
+ <v>TypeDescr = atom() | string()</v>
+ </type>
+ <desc>
+ <p>Returns the type description of a type number used in
+ <c>MemoryData</c>.
+ Valid <c>TypeNo</c>s are in the range returned by
+ <seealso marker="#type_no_range/1">type_no_range/1</seealso> on
+ this specific memory allocation map. If <c>TypeNo</c> is an
+ invalid integer, <c>invalid_type</c> is returned.</p>
+ </desc>
+ </func>
+ <func>
+ <name>type_no_range(MemoryData) -> {Min, Max}</name>
+ <fsummary>Returns the memory block type numbers</fsummary>
+ <type>
+ <v>MemoryData = {term(), AllocList}</v>
+ <v>AllocList = [Desc]</v>
+ <v>Desc = {int(), int(), int(), PidDesc}</v>
+ <v>PidDesc = {int(), int(), int()} | undefined</v>
+ <v>Min = int()</v>
+ <v>Max = int()</v>
+ </type>
+ <desc>
+ <marker id="type_no_range_1"></marker>
+ <p>Returns the memory block type number range used in
+ <c>MemoryData</c>. When the memory allocation map was generated
+ by an Erlang 5.3/OTP R9C or newer emulator, all integers <c>T</c>
+ that satisfy <c>Min</c> &lt;= <c>T</c> &lt;= <c>Max</c> are
+ valid type numbers. When the memory allocation map was generated
+ by a pre Erlang 5.3/OTP R9C emulator, all integers in the
+ range are <em>not</em> valid type numbers.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>See Also</title>
+ <p><seealso marker="erts:erts_alloc">erts_alloc(3)</seealso>,
+ <seealso marker="erts:erl">erl(1)</seealso></p>
+ </section>
+</erlref>
+
diff --git a/lib/tools/doc/src/make.dep b/lib/tools/doc/src/make.dep
new file mode 100644
index 0000000000..11fa090d6f
--- /dev/null
+++ b/lib/tools/doc/src/make.dep
@@ -0,0 +1,33 @@
+# ----------------------------------------------------
+# >>>> Do not edit this file <<<<
+# This file was automaticly generated by
+# /home/otp/bin/docdepend
+# ----------------------------------------------------
+
+
+# ----------------------------------------------------
+# TeX files that the DVI file depend on
+# ----------------------------------------------------
+
+book.dvi: book.tex cover.tex cover_chapter.tex cprof.tex \
+ cprof_chapter.tex eprof.tex erlang_mode.tex \
+ erlang_mode_chapter.tex fprof.tex fprof_chapter.tex \
+ instrument.tex make.tex part.tex ref_man.tex \
+ tags.tex xref.tex xref_chapter.tex
+
+# ----------------------------------------------------
+# Source inlined when transforming from source to LaTeX
+# ----------------------------------------------------
+
+book.tex: ref_man.xml
+
+cprof.tex: ../../../../system/doc/definitions/term.defs
+
+xref.tex: ../../../../system/doc/definitions/term.defs
+
+# ----------------------------------------------------
+# Pictures that the DVI file depend on
+# ----------------------------------------------------
+
+book.dvi: venn1.ps venn2.ps
+
diff --git a/lib/tools/doc/src/make.xml b/lib/tools/doc/src/make.xml
new file mode 100644
index 0000000000..f13514d99f
--- /dev/null
+++ b/lib/tools/doc/src/make.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>1996</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>make</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <module>make</module>
+ <modulesummary>A Make Utility for Erlang</modulesummary>
+ <description>
+ <p>The module <c>make</c> provides a set of functions similar to
+ the UNIX type <c>Make</c> functions.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>all() -> up_to_date | error</name>
+ <name>all(Options) -> up_to_date | error</name>
+ <fsummary>Compile a set of modules.</fsummary>
+ <type>
+ <v>Options = [Option]</v>
+ <v>&nbsp;Option = noexec | load | netload | &lt;compiler option&gt;</v>
+ </type>
+ <desc>
+ <p>This function first looks in the current working directory
+ for a file named <c>Emakefile</c> (see below) specifying the
+ set of modules to compile and the compile options to use. If
+ no such file is found, the set of modules to compile
+ defaults to all modules in the current working
+ directory.</p>
+ <p>Traversing the set of modules, it then recompiles every module for
+ which at least one of the following conditions apply:</p>
+ <list type="bulleted">
+ <item>there is no object file, or</item>
+ <item>the source file has been modified since it was last compiled,
+ or,</item>
+ <item>an include file has been modified since the source file was
+ last compiled.</item>
+ </list>
+ <p>As a side effect, the function prints the name of each module it
+ tries to compile. If compilation fails for a module, the make
+ procedure stops and <c>error</c> is returned.</p>
+ <p><c>Options</c> is a list of make- and compiler options.
+ The following make options exist:</p>
+ <list type="bulleted">
+ <item><c>noexec</c> <br></br>
+
+ No execution mode. Just prints the name of each module that needs
+ to be compiled.</item>
+ <item><c>load</c> <br></br>
+
+ Load mode. Loads all recompiled modules.</item>
+ <item><c>netload</c> <br></br>
+
+ Net load mode. Loads all recompiled modules an all known nodes.</item>
+ </list>
+ <p>All items in <c>Options</c> that are not make options are assumed
+ to be compiler options and are passed as-is to
+ <c>compile:file/2</c>. <c>Options</c> defaults to <c>[]</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>files(ModFiles) -> up_to_date | error</name>
+ <name>files(ModFiles, Options) -> up_to_date | error</name>
+ <fsummary>Compile a set of modules.</fsummary>
+ <type>
+ <v>ModFiles = [Module | File]</v>
+ <v>&nbsp;Module = atom()</v>
+ <v>&nbsp;File = string()</v>
+ <v>Options = [Option]</v>
+ <v>&nbsp;Option = noexec | load | netload | &lt;compiler option&gt;</v>
+ </type>
+ <desc>
+ <p><c>files/1,2</c> does exactly the same thing as <c>all/0,1</c> but
+ for the specified <c>ModFiles</c>, which is a list of module or
+ file names. The file extension <c>.erl</c> may be omitted.</p>
+ <p>The <c>Emakefile</c> (if it exists) in the current
+ directory is searched for compiler options for each module. If
+ a given module does not exist in <c>Emakefile</c> or if
+ <c>Emakefile</c> does not exist, the module is still compiled.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>Emakefile</title>
+ <p><c>make:all/0,1</c> and <c>make:files/1,2</c> looks in the
+ current working directory for a file named <c>Emakefile</c>. If
+ it exists, <c>Emakefile</c> should contain elements like this:</p>
+ <code type="none">
+Modules.
+{Modules,Options}. </code>
+ <p><c>Modules</c> is an atom or a list of atoms. It can be
+ </p>
+ <list type="bulleted">
+ <item>a module name, e.g. <c>file1</c></item>
+ <item>a module name in another directory,
+ e.g. <c>../foo/file3</c></item>
+ <item>a set of modules specified with a wildcards,
+ e.g. <c>'file*'</c></item>
+ <item>a wildcard indicating all modules in current directory,
+ i.e. <c>'*'</c></item>
+ <item>a list of any of the above,
+ e.g. <c>['file*','../foo/file3','File4']</c></item>
+ </list>
+ <p><c>Options</c> is a list of compiler options.
+ </p>
+ <p><c>Emakefile</c> is read from top to bottom. If a module
+ matches more than one entry, the first match is valid. For
+ example, the following <c>Emakefile</c> means that <c>file1</c>
+ shall be compiled with the options
+ <c>[debug_info,{i,"../foo"}]</c>, while all other files in the
+ current directory shall be compiled with only the
+ <c>debug_info</c> flag.</p>
+ <code type="none">
+{'file1',[debug_info,{i,"../foo"}]}.
+{'*',[debug_info]}. </code>
+ <p></p>
+ </section>
+</erlref>
+
diff --git a/lib/tools/doc/src/note.gif b/lib/tools/doc/src/note.gif
new file mode 100644
index 0000000000..6fffe30419
--- /dev/null
+++ b/lib/tools/doc/src/note.gif
Binary files differ
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
new file mode 100644
index 0000000000..59f600145e
--- /dev/null
+++ b/lib/tools/doc/src/notes.xml
@@ -0,0 +1,475 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2004</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Tools Release Notes</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>notes.xml</file>
+ </header>
+ <p>This document describes the changes made to the Tools application.</p>
+
+<section><title>Tools 2.6.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>The coverage analysis tool <c>cover</c> has been
+ improved when it comes to handling list and bit string
+ comprehensions (a counter for each qualifier), bit syntax
+ expressions (the Value and Size expressions), and try
+ expressions (the body called <c>Exprs</c> in the Reference
+ Manual). A few (not all) situations where several
+ expressions are put on the same line are also handled
+ better than before.</p>
+ <p>Own Id: OTP-8188 Aux Id: seq11397</p>
+ </item>
+ <item>
+ <p>When loading Cover compiled code on remote nodes
+ running code in the loaded module, a <c>badarg</c>
+ failure was sometimes the result. This bug has been fixed.</p>
+ <p>Own Id: OTP-8270 Aux Id: seq11423</p>
+ </item>
+ <item>
+ <p>The short-circuit operators <c>andalso</c> and
+ <c>orelse</c> are now handled correctly by the coverage
+ analysis tool <c>cover</c> (it is no longer checked
+ that the second argument returns a Boolean value.)</p>
+ <p>Own Id: OTP-8273</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.6.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p><c>cover</c> now properly escapes greater-than and
+ less-than characters in comments in HTML reports. (Thanks
+ to Magnus Henoch.)</p>
+ <p>
+ Own Id: OTP-7939</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.6.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ xref:start/1 does now allow anonymous XREF processes to
+ be started</p>
+ <p>
+ Own Id: OTP-7831</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.6.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>A bug in the Xref scanner has been fixed.</p>
+ <p>
+ Own Id: OTP-7423</p>
+ </item>
+ <item>
+ <p>A bug in Fprof where the function 'undefined' appeared
+ to call 'undefined' has been corrected.</p>
+ <p>
+ Own Id: OTP-7509</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.6.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The documentation has been updated so as to reflect
+ the last updates of the Erlang shell as well as the minor
+ modifications of the control sequence <c>p</c> of the
+ <c>io_lib</c> module.</p> <p>Superfluous empty lines have
+ been removed from code examples and from Erlang shell
+ examples.</p>
+ <p>
+ Own Id: OTP-6944 Aux Id: OTP-6554, OTP-6911 </p>
+ </item>
+ <item>
+ <p><c>tuple_size/1</c> and <c>byte_size/1</c> have been
+ substituted for <c>size/1</c>.</p>
+ <p>
+ Own Id: OTP-7009</p>
+ </item>
+ <item>
+ <p>The coverage analysis tool <c>cover</c> now handles
+ the short-circuit Boolean expressions <c>andalso/2</c>
+ and <c>orelse/2</c> properly.</p>
+ <p>
+ Own Id: OTP-7095</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Tools 2.6</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The <c>cover</c> tool could use huge amounts of memory
+ when used in a distributed system.</p>
+ <p>
+ Own Id: OTP-6758</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+
+ <section>
+ <title>Tools 2.5.5</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Missing buffer-local declaration in erlang.el has been
+ added. Before this fix there could arise problems in
+ other emacs modes after visiting a buffer using the
+ erlang mode.</p>
+ <p>Own Id: OTP-6721</p>
+ </item>
+ <item>
+ <p>Key-map for 'backward-delete-char-untabif updated to work
+ properly with Xemacs.</p>
+ <p>Own Id: OTP-6723</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Minor updates of Xref.</p>
+ <p>Own Id: OTP-6586</p>
+ </item>
+ <item>
+ <p>Minor Makefile changes.</p>
+ <p>Own Id: OTP-6689 Aux Id: OTP-6742 </p>
+ </item>
+ <item>
+ <p>"C-u C-c C-k" now does a compile with both "debug_info"
+ and "export_all".</p>
+ <p>Own Id: OTP-6741</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.5.4.1</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Changes due to internal interface changes in the erts
+ application which are needed at compile-time. No
+ functionality has been changed.</p>
+ <p>Own Id: OTP-6611 Aux Id: OTP-6580 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.5.4</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Made change to support the function erlang-find-tag for
+ xemacs and emacs-21.</p>
+ <p>Own Id: OTP-6512</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Minor updates of xref for future compatibility.</p>
+ <p>Own Id: OTP-6513</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.5.3</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p><c>eprof</c> did not work reliably in the SMP emulator,
+ because the trace receiver process could not process the
+ trace messages fast enough. Therefore, <c>eprof</c> now
+ blocks the other schedulers while profiling.</p>
+ <p>Own Id: OTP-6373</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.5.2</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Fprof traces could become truncated for the SMP emulator.
+ This bug has now been corrected.</p>
+ <p>Own Id: OTP-6246</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.5.1</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>eprof now works somewhat better in the SMP emulator.</p>
+ <p>Own Id: OTP-6152</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.5</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Fixed some bugs in <c>make</c>:</p>
+ <p><c>make:files/1,2</c> can now handle a file in another
+ directory as argument, similar to <c>make:all/0,1</c>.</p>
+ <p>When specifying a file name including the <c>.erl</c>
+ extension in <c>Emakefile</c>, <c>make:all/0,1</c> looked
+ for the object code in the wrong place.</p>
+ <p>When specifying a file name including the <c>.erl</c>
+ extension in <c>Emakefile</c> and some compile options
+ for the file, <c>make:files/0,1</c> did not use the
+ options as it should do.</p>
+ <p>Own Id: OTP-6057 Aux Id: seq10299</p>
+ </item>
+ <item>
+ <p><c>cover</c>: When <c>cover:stop()</c> was called,
+ the cover compiled code was not unloaded (as stated in
+ the documentation) but simply marked as 'old'. This
+ meant that processes lingering in (or with funs
+ referencing to) the cover compiled code would survive
+ even when the cover server and its ETS tables was
+ terminated.</p>
+ <p>Now the cover compiled code is unloaded, meaning that
+ processes lingering in/with references to it will be
+ killed when <c>cover:stop</c> is called, instead of
+ later crashing with <c>badarg</c> when trying to bump
+ counters in ETS tables no longer existing.</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Replaced call to deprecated function
+ <c>file:file_info/1</c> with call to
+ <c>filelib:is_dir/1</c> and <c>filelib:is_regular/1</c>
+ in <c>tags.erl</c>.</p>
+ <p>Own Id: OTP-6079</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.4.7</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>A bug in <c>fprof</c> profiling causing erroneous
+ inconsistent trace failure has been corrected.</p>
+ <p>Own Id: OTP-5922 Aux Id: seq10203 </p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.4.6</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Emacs: <c>erlang-man-function</c> and
+ <c>erlang-man-module</c> used a pattern matching to find
+ the requested module that sometimes yielded unexpected
+ results. For example, <c>erlang-man-module file</c> would
+ display the man page for <c>CosFileTransfer_File</c>.</p>
+ <p>Own Id: OTP-5746 Aux Id: seq10096</p>
+ </item>
+ <item>
+ <p>Some compiler warnings and Dialyzer warnings were
+ eliminated in the Tools application.</p>
+ <p>When tracing to a port (which <c>fprof</c> does),
+ there could be fake schedule out/schedule in messages
+ sent for a process that had exited.</p>
+ <p>Own Id: OTP-5757</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.4.5</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The cross reference tool <c>xref</c> did not handle the new
+ <c>fun M:F/A</c> construct properly. This problem has been
+ fixed.</p>
+ <p>Own Id: OTP-5653</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.4.4</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The <c>cover</c> tool did not escape '&lt;' and '&gt;' not
+ being part of HTML tags in HTML log files.</p>
+ <p>Own Id: OTP-5588</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.4.3</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>It is now possible to encrypt the debug information in
+ beam files, to help keep the source code secret. See
+ <c>compile(3)</c> for how to provide the key for encrypting,
+ and <c>beam_lib(3)</c> for how to provide the key for
+ decryption so that tools such as Debugger, <c>xref</c>, or
+ <c>cover</c> can be used.</p>
+ <p>The <c>beam_lib:chunks/2</c> functions now accepts an
+ additional chunk type '<c>compile_info</c>' to retrieve
+ the compilation information directly as a term. (Thanks
+ to Tobias Lindahl.)</p>
+ <p>Own Id: OTP-5460 Aux Id: seq9787</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.4.2</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The <c>cover</c> tool could not analyze empty modules on
+ module level.</p>
+ <p>Own Id: OTP-5418</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.4.1</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The <c>xref</c> analysis <c>locals_not_used</c> could
+ return too many functions. This problem has been fixed.</p>
+ <p>Own Id: OTP-5071</p>
+ </item>
+ <item>
+ <p>The <c>cover</c> tool could not always compile parse
+ transformed modules. This problem has been fixed.</p>
+ <p>Own Id: OTP-5305</p>
+ </item>
+ </list>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/tools/doc/src/notes_history.xml b/lib/tools/doc/src/notes_history.xml
new file mode 100644
index 0000000000..ef5ce1c03d
--- /dev/null
+++ b/lib/tools/doc/src/notes_history.xml
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2006</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>Tools Release Notes</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+
+ <section>
+ <title>Tools 2.4</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The Erlang Emacs mode now properly handles strings that
+ have $ or ^ as the last character.</p>
+ <p>Own Id: OTP-4697</p>
+ </item>
+ <item>
+ <p><c>xref</c>: The unresolved arity (-1) is now recognized
+ in analyses and queries.</p>
+ <p>Own Id: OTP-4778</p>
+ </item>
+ <item>
+ <p><c>cover</c> does no longer hang if an interface function
+ is called on a remote node - it returns
+ <c>{error,not_main_node}</c>.</p>
+ <p>Own Id: OTP-5031</p>
+ </item>
+ <item>
+ <p><c>fprof</c>: Time spent in the last function in a chain,
+ i.e. a function which did not call another function, and
+ the time when a process was scheduled out, was charged on
+ the above function. This resulted in own time in many
+ cases being bigger than acc time since the time a process
+ was scheduled out was charged on the function from which
+ the process was scheduled out. This is now corrected.</p>
+ <p>Own Id: OTP-5073</p>
+ </item>
+ <item>
+ <p>Previous patch from open source messed up \\M-q so part of
+ that patch was backed out.</p>
+ <p>Own Id: OTP-5074</p>
+ </item>
+ <item>
+ <p><c>cover</c>: Added "Exclude Included Functions". If
+ "real code" is included in a modules which is cover
+ compiled, there will be no bumps for lines in the
+ included file. Earlier this would cause faulty bumps for
+ lines in the module, i.e. if the code was on line 4 in
+ the included file it would produce a bump for line 4 in
+ the module. Lines in included files are now just
+ disregarded.</p>
+ <p>Own Id: OTP-5122</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Added support for try-catch to the Erlang mode for Emacs.
+ However there are still some known problems with some of
+ the more advanced variants especially including separate
+ of-clauses.</p>
+ <p>Own Id: OTP-4594</p>
+ </item>
+ <item>
+ <p>Improvments for support of Emacs 21 contributed by Dave
+ Love. The bulk of the changes are actually cosmetic
+ commentary/doc fixes. The significant ones make it play
+ better with Emacs 21 with up-to-date facilities. In
+ particular, support for compilation error messages from
+ an inferior erl (as opposed to batch compilation) works
+ in the released Emacs 21, and currently with the
+ development Emacs.</p>
+ <p>Own Id: OTP-5019</p>
+ </item>
+ <item>
+ <p>Added a skeletons for an Erlang test-suite for both the
+ ts-frontend and the ct-frontend (this frontend is
+ Ericsson internal). Also altered some of the old
+ skeletons to get a uniform look and feel.</p>
+ <p>Own Id: OTP-5058</p>
+ </item>
+ <item>
+ <p>The Erlang mode for Emacs now supports the new guard
+ <c>is_boolean</c>.</p>
+ <p>Own Id: OTP-5059</p>
+ </item>
+ <item>
+ <p><c>cover</c>: Adjustments to handle new syntax of
+ try-catch.</p>
+ <p>Own Id: OTP-5154</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
+ <title>Tools 2.3</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Totally rewritten the interface for WebCover. Can now
+ compile both <c>.erl</c> and <c>.beam</c> files and
+ export/import cover data.</p>
+ <p>Own Id: OTP-4706</p>
+ </item>
+ <item>
+ <p><c>cover</c> does no longer report coverage on lines which
+ are not executed.</p>
+ <p>Own Id: OTP-4734</p>
+ </item>
+ <item>
+ <p>Erlang mode for Emacs: Fixed so that the generation of new
+ function clauses works also for guarded functions.</p>
+ <p>Own Id: OTP-3697</p>
+ </item>
+ <item>
+ <p>Erlang mode for Emacs: Fixed so that you do not get
+ the error message "unbalanced parenthesis" when indenting
+ correct code including bit syntax.</p>
+ <p>Own Id: OTP-4526</p>
+ </item>
+ <item>
+ <p>Erlang mode for Emacs: The guard <c>function</c> is now
+ colored.</p>
+ <p>Own Id: OTP-4533</p>
+ </item>
+ <item>
+ <p>Erlang mode for Emacs: Indentation of macros is handled
+ correctly in all cases.</p>
+ <p>Own Id: OTP-4561, OTP-4687</p>
+ </item>
+ <item>
+ <p><c>is_*</c> guards are now colored.</p>
+ <p>Own Id: OTP-4562</p>
+ </item>
+ <item>
+ <p>Erlang mode for Emacs: Now handles the fact that a function
+ argument may be a guard expression. (That is useful when
+ writing test case code.)</p>
+ <p>Own Id: OTP-4579</p>
+ </item>
+ <item>
+ <p>Erlang mode for Emacs: Keywords <c>andalso</c> and
+ <c>orelse</c> are now colored.</p>
+ <p>Own Id: OTP-4580</p>
+ </item>
+ <item>
+ <p>Erlang mode for Emacs: Fixed bug in function that calculates
+ the arity of an Erlang function.</p>
+ <p>Own Id: OTP-4581</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>Added functions <c>cover:start(Nodes)</c> and
+ <c>cover:stop(Nodes)</c>. Cover compiled modules will be
+ loaded on all nodes added with <c>cover:start(Nodes)</c>.
+ <c>cover:stop(Nodes)</c> will collect coverage data from
+ the stopped nodes and merge it with data collected on
+ the main (controller) node.</p>
+ <p><c>cover:analyse/1,2,3</c> and
+ <c>cover:analyse_to_file/1,2,3</c> will also collect data
+ from all nodes before analysing.</p>
+ <p>Own Id: OTP-4177</p>
+ </item>
+ <item>
+ <p>The module attribute tag <c>deprecated</c> is used by
+ <c>xref</c> to find calls to deprecated functions.
+ The <c>m/1</c>, <c>d/1</c>, and <c>analyze/2,3</c> functions
+ have been updated to return calls to deprecated functions.
+ See also <c>xref(3)</c> for more details.</p>
+ <p>Own Id: OTP-4695</p>
+ </item>
+ <item>
+ <p>Added functions <c>cover:compile_beam/1</c> and
+ <c>cover:compile_beam_directory/0,1</c>. These functions use
+ abstract code from existing beam files when cover compiling.</p>
+ <p>Added option <c>html</c> to
+ <c>cover:analyse_to_file/1,2,3</c>. Instead of plain text,
+ a HTML file is generated with all uncovered lines colored
+ red.</p>
+ <p>Added functions <c>cover:export/1,2</c> and
+ <c>cover:import/1</c>. These functions can be used to export
+ current coverage data to a file, and then import the data
+ in a later session. Data can be exported for one single
+ module or for all currently cover compiled modules.</p>
+ <p>Own Id: OTP-4702</p>
+ </item>
+ <item>
+ <p>Erlang mode for Emacs: Added function
+ <c>erlang-align-arrows</c>.</p>
+ <p>Own Id: OTP-4737</p>
+ </item>
+ <item>
+ <p>The interface for the <c>instrument</c> module has been
+ slightly changed. Also some new functionality has been
+ added. See <c>instrument(3)</c> for more information.</p>
+ <p>(*** POTENTIAL INCOMPATIBILITY ***)</p>
+ <p>Own Id: OTP-4761 <br></br>
+
+ Aux Id: OTP-4534</p>
+ </item>
+ </list>
+ </section>
+ </section>
+</chapter>
+
diff --git a/lib/tools/doc/src/part.xml b/lib/tools/doc/src/part.xml
new file mode 100644
index 0000000000..3e02086b80
--- /dev/null
+++ b/lib/tools/doc/src/part.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Tools User's Guide</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <description>
+ <p>The <em>Tools</em> application contains a number of stand-alone
+ tools, which are useful when developing Erlang programs.</p>
+ <taglist>
+ <tag><em>cover</em></tag>
+ <item>A coverage analysis tool for Erlang.</item>
+ <tag><em>cprof</em></tag>
+ <item>A profiling tool that shows how many
+ times each function is called. Uses a kind of local call trace
+ breakpoints containing counters to achieve very low runtime
+ performance degradation.</item>
+ <tag><em>emacs - (erlang.el and erlang-start.el)</em></tag>
+ <item>This package provides support
+ for the programming language Erlang in Emacs. The package provides an
+ editing mode with lots of bells and whistles, compilation
+ support, and it makes it possible for the user to start Erlang
+ shells that run inside Emacs.</item>
+ <tag><em>eprof</em></tag>
+ <item>A time profiling tool; measure how time is used in Erlang
+ programs. Erlang programs. Predecessor of <em>fprof</em> (see below).</item>
+ <tag><em>fprof</em></tag>
+ <item>Another Erlang profiler; measure how time is used in your
+ Erlang programs. Uses trace to file to minimize runtime
+ performance impact, and displays time for calling and called
+ functions.</item>
+ <tag><em>instrument</em></tag>
+ <item>Utility functions for obtaining and analysing resource usage
+ in an instrumented Erlang runtime system.</item>
+ <tag><em>make</em></tag>
+ <item>A make utility for Erlang similar to UNIX make.</item>
+ <tag><em>tags</em></tag>
+ <item>A tool for generating Emacs TAGS files from Erlang source
+ files.</item>
+ <tag><em>xref</em></tag>
+ <item>A cross reference tool. Can be used to check dependencies
+ between functions, modules, applications and releases.</item>
+ </taglist>
+ </description>
+ <xi:include href="cover_chapter.xml"/>
+ <xi:include href="cprof_chapter.xml"/>
+ <xi:include href="erlang_mode_chapter.xml"/>
+ <xi:include href="fprof_chapter.xml"/>
+ <xi:include href="xref_chapter.xml"/>
+</part>
+
diff --git a/lib/tools/doc/src/part_notes.xml b/lib/tools/doc/src/part_notes.xml
new file mode 100644
index 0000000000..b8b67889c2
--- /dev/null
+++ b/lib/tools/doc/src/part_notes.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>2004</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Tools Release Notes</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <description>
+ <p>The <em>Tools</em> application contains a number of stand-alone
+ tools, which are useful when developing Erlang programs.</p>
+ <p>For information about older versions, see
+ <url href="part_notes_history_frame.html">Release Notes History</url>.</p>
+ </description>
+ <xi:include href="notes.xml"/>
+</part>
+
diff --git a/lib/tools/doc/src/part_notes_history.xml b/lib/tools/doc/src/part_notes_history.xml
new file mode 100644
index 0000000000..b40b530c02
--- /dev/null
+++ b/lib/tools/doc/src/part_notes_history.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part>
+ <header>
+ <copyright>
+ <year>2006</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>Tools Release Notes History</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <description>
+ <p>The <em>Tools</em> application contains a number of stand-alone
+ tools, which are useful when developing Erlang programs.</p>
+ </description>
+ <include file="notes_history"></include>
+</part>
+
diff --git a/lib/tools/doc/src/ref_man.xml b/lib/tools/doc/src/ref_man.xml
new file mode 100644
index 0000000000..aea74e3746
--- /dev/null
+++ b/lib/tools/doc/src/ref_man.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE application SYSTEM "application.dtd">
+
+<application xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Tools Reference Manual</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <description>
+ <p>The <em>Tools</em> application contains a number of stand-alone
+ tools, which are useful when developing Erlang programs.</p>
+ <taglist>
+ <tag><em>cover</em></tag>
+ <item>A coverage analysis tool for Erlang.</item>
+ <tag><em>cprof</em></tag>
+ <item>A profiling tool that shows how many
+ times each function is called. Uses a kind of local call trace
+ breakpoints containing counters to achieve very low runtime
+ performance degradation.</item>
+ <tag><em>erlang.el</em>- Erlang mode for Emacs</tag>
+ <item>Editing support such as indentation, syntax highlighting,
+ electric commands, module name verification, comment support
+ including paragraph filling, skeletons, tags support and more
+ for erlang source code. </item>
+ <tag><em>eprof</em></tag>
+ <item>A time profiling tool; measure how time is used in Erlang
+ programs. Predecessor of <em>fprof</em> (see below).</item>
+ <tag><em>fprof</em></tag>
+ <item>Another Erlang profiler; measure how time is used in your
+ Erlang programs. Uses trace to file to minimize runtime
+ performance impact, and displays time for calling and called
+ functions.</item>
+ <tag><em>instrument</em></tag>
+ <item>Utility functions for obtaining and analysing resource usage
+ in an instrumented Erlang runtime system.</item>
+ <tag><em>make</em></tag>
+ <item>A make utility for Erlang similar to UNIX make.</item>
+ <tag><em>tags</em></tag>
+ <item>A tool for generating Emacs TAGS files from Erlang source
+ files.</item>
+ <tag><em>xref</em></tag>
+ <item>A cross reference tool. Can be used to check dependencies
+ between functions, modules, applications and releases.</item>
+ </taglist>
+ </description>
+ <xi:include href="cover.xml"/>
+ <xi:include href="cprof.xml"/>
+ <xi:include href="eprof.xml"/>
+ <xi:include href="erlang_mode.xml"/>
+ <xi:include href="fprof.xml"/>
+ <xi:include href="instrument.xml"/>
+ <xi:include href="make.xml"/>
+ <xi:include href="tags.xml"/>
+ <xi:include href="xref.xml"/>
+</application>
+
diff --git a/lib/tools/doc/src/tags.xml b/lib/tools/doc/src/tags.xml
new file mode 100644
index 0000000000..5e1da25acf
--- /dev/null
+++ b/lib/tools/doc/src/tags.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>1998</year>
+ <year>2007</year>
+ <holder>Ericsson AB, All Rights Reserved</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+ </legalnotice>
+
+ <title>tags</title>
+ <prepared>Anders Lindgren</prepared>
+ <responsible></responsible>
+ <docno>1</docno>
+ <date>98-03-11</date>
+ <rev>A</rev>
+ <file>tags.sgml</file>
+ </header>
+ <module>tags</module>
+ <modulesummary>Generate Emacs TAGS file from Erlang source files</modulesummary>
+ <description>
+ <p>A <c>TAGS</c> file is used by Emacs to find function and variable
+ definitions in any source file in large projects. This module can
+ generate a <c>TAGS</c> file from Erlang source files. It recognises
+ functions, records, and macro definitions.</p>
+ </description>
+ <funcs>
+ <func>
+ <name>file(File [, Options])</name>
+ <fsummary>Create a <c>TAGS</c>file for the file <c>File</c>.</fsummary>
+ <desc>
+ <p>Create a <c>TAGS</c> file for the file <c>File</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>files(FileList [, Options])</name>
+ <fsummary>Create a TAGS file for the files in the list<c>FileList</c>.</fsummary>
+ <desc>
+ <p>Create a TAGS file for the files in the list
+ <c>FileList</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>dir(Dir [, Options])</name>
+ <fsummary>Create a TAGS file for all files in directory<c>Dir</c>.</fsummary>
+ <desc>
+ <p>Create a TAGS file for all files in directory
+ <c>Dir</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>dirs(DirList [, Options])</name>
+ <fsummary>Create a TAGS file for all files in any directory in<c>DirList</c>.</fsummary>
+ <desc>
+ <p>Create a TAGS file for all files in any directory in
+ <c>DirList</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>subdir(Dir [, Options])</name>
+ <fsummary>Descend recursively down the directory <c>Dir</c>and create a <c>TAGS</c>file based on all files found.</fsummary>
+ <desc>
+ <p>Descend recursively down the directory <c>Dir</c> and
+ create a <c>TAGS</c> file based on all files found.</p>
+ </desc>
+ </func>
+ <func>
+ <name>subdirs(DirList [, Options])</name>
+ <fsummary>Descend recursively down all the directories in<c>DirList</c>and create a <c>TAGS</c>file based on all files found.</fsummary>
+ <desc>
+ <p>Descend recursively down all the directories in
+ <c>DirList</c> and create a <c>TAGS</c> file based on all
+ files found.</p>
+ </desc>
+ </func>
+ <func>
+ <name>root([Options])</name>
+ <fsummary>Create a <c>TAGS</c>file covering all files in the Erlang distribution.</fsummary>
+ <desc>
+ <p>Create a <c>TAGS</c> file covering all files in
+ the Erlang distribution.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>OPTIONS</title>
+ <p>The functions above have an optional argument, <c>Options</c>. It is a
+ list which can contain the following elements:</p>
+ <list type="bulleted">
+ <item><c>{outfile, NameOfTAGSFile}</c> Create a <c>TAGS</c> file named
+ <c>NameOfTAGSFile</c>.
+ </item>
+ <item><c>{outdir, NameOfDirectory}</c> Create a file named
+ <c>TAGS</c> in the directory <c>NameOfDirectory</c>.</item>
+ </list>
+ <p>The default behaviour is to create a file named <c>TAGS</c> in the current
+ directory.</p>
+ </section>
+
+ <section>
+ <title>Examples</title>
+ <list type="bulleted">
+ <item>
+ <p><c>tags:root([{outfile, "root.TAGS"}]).</c> <br></br>
+</p>
+ <p>This command will create a file named <c>root.TAGS</c> in the current
+ directory. The file will contain references to all Erlang source
+ files in the Erlang distribution.</p>
+ </item>
+ <item>
+ <p><c>tags:files(["foo.erl", "bar.erl", "baz.erl"], [{outdir, "../projectdir"}]). </c> <br></br>
+</p>
+ <p>Here we create file named <c>TAGS</c> placed it in the directory
+ <c>../projectdir</c>. The file contains information about the
+ functions, records, and macro definitions of the three files.</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>SEE ALSO</title>
+ <list type="bulleted">
+ <item>Richard M. Stallman. GNU Emacs Manual, chapter "Editing Programs",
+ section "Tag Tables". Free Software Foundation, 1995.
+ </item>
+ <item>Anders Lindgren. The Erlang editing mode for Emacs. Ericsson,
+ 1998.</item>
+ </list>
+ </section>
+</erlref>
+
diff --git a/lib/tools/doc/src/venn1.fig b/lib/tools/doc/src/venn1.fig
new file mode 100644
index 0000000000..a826756047
--- /dev/null
+++ b/lib/tools/doc/src/venn1.fig
@@ -0,0 +1,63 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+6 4368 1485 7027 4139
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 3177.742 2812.000 4570 2137 4725 2812 4570 3487
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 9043.057 2812.000 5400 4112 5175 2812 5400 1512
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 2307.694 2812.000 6003 1512 6225 2812 6003 4112
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 5700 2812 1327 1327 5700 2812 4800 1837
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 1
+ 6681 3706
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 6675 1912 6675 3712
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 2
+ 4368 2806 6675 2806
+2 1 0 1 0 0 100 0 1 0.000 0 0 -1 0 0 2
+ 6675 3149 6985 3149
+-6
+6 1275 3075 3000 4800
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 563.250 3905.000 1434 3485 1530 3905 1434 4325
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 23.692 3905.000 2326 3096 2464 3905 2326 4714
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 4217.432 3905.000 1950 4714 1810 3905 1950 3096
+6 1275 3675 2775 4200
+6 2026 3679 2251 4129
+6 2026 3679 2251 4129
+4 0 0 100 0 0 8 0.0000 4 75 180 2078 3794 XU\001
+4 0 0 100 0 0 8 0.0000 4 75 165 2071 3944 and\001
+4 0 0 100 0 0 8 0.0000 4 75 165 2078 4093 LU\001
+-6
+-6
+4 0 0 100 0 0 8 0.0000 4 75 165 1594 3934 LU\001
+4 0 0 100 0 0 8 0.0000 4 75 180 2634 3934 XU\001
+4 0 0 100 0 0 8 0.0000 4 75 180 1337 3934 UU\001
+-6
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 2137 3905 826 826 2137 3905 1577 3298
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 1
+ 2747 4461
+-6
+6 1275 825 3000 2850
+6 2760 1516 2820 2006
+4 0 0 100 0 0 8 0.0000 4 75 90 2760 1576 U\001
+4 0 0 100 0 0 8 0.0000 4 75 75 2760 2006 B\001
+-6
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 2115 1665 826 826 2115 1665 1555 1058
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 1
+ 2725 2221
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2722 1105 2722 2225
+2 1 0 1 0 0 100 0 1 0.000 0 0 -1 0 0 2
+ 2722 1875 2917 1875
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 2
+ 1286 1665 2722 1665
+4 0 0 100 0 0 11 0.0000 4 105 645 1830 2785 Definition\001
+4 0 0 100 0 0 8 0.0000 4 75 90 2022 1338 X\001
+4 0 0 100 0 0 8 0.0000 4 75 75 2022 2085 L\001
+-6
+4 0 0 100 0 0 11 0.0000 4 105 240 2025 5025 Use\001
+4 0 0 101 0 0 11 0.0000 4 105 1155 5127 4544 Definition and Use\001
diff --git a/lib/tools/doc/src/venn1.gif b/lib/tools/doc/src/venn1.gif
new file mode 100644
index 0000000000..e40bcfb8ab
--- /dev/null
+++ b/lib/tools/doc/src/venn1.gif
Binary files differ
diff --git a/lib/tools/doc/src/venn1.ps b/lib/tools/doc/src/venn1.ps
new file mode 100644
index 0000000000..9c12048728
--- /dev/null
+++ b/lib/tools/doc/src/venn1.ps
@@ -0,0 +1,205 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: venn1.ps
+%%Creator: fig2dev Version 3.2 Patchlevel 1
+%%CreationDate: Tue Sep 19 19:28:28 2000
+%%For: hasse@helios (Hans Bolinder)
+%%Orientation: Portrait
+%%BoundingBox: 0 0 347 253
+%%Pages: 0
+%%BeginSetup
+%%EndSetup
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-76.0 302.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n -1000 6025 m -1000 -1000 l 8035 -1000 l 8035 6025 l cp clip
+ 0.06000 0.06000 sc
+/Times-Roman ff 165.00 scf sf
+5127 4544 m
+gs 1 -1 sc (Definition and Use) col0 sh gr
+% Polyline
+7.500 slw
+n 6675 3149 m 6985 3149 l gs 0.95 setgray ef gr gs col0 s gr
+/Times-Roman ff 120.00 scf sf
+2078 3794 m
+gs 1 -1 sc (XU) col0 sh gr
+/Times-Roman ff 120.00 scf sf
+2071 3944 m
+gs 1 -1 sc (and) col0 sh gr
+/Times-Roman ff 120.00 scf sf
+2078 4093 m
+gs 1 -1 sc (LU) col0 sh gr
+/Times-Roman ff 120.00 scf sf
+1594 3934 m
+gs 1 -1 sc (LU) col0 sh gr
+/Times-Roman ff 120.00 scf sf
+2634 3934 m
+gs 1 -1 sc (XU) col0 sh gr
+/Times-Roman ff 120.00 scf sf
+1337 3934 m
+gs 1 -1 sc (UU) col0 sh gr
+/Times-Roman ff 120.00 scf sf
+2760 1576 m
+gs 1 -1 sc (U) col0 sh gr
+/Times-Roman ff 120.00 scf sf
+2760 2006 m
+gs 1 -1 sc (B) col0 sh gr
+% Polyline
+n 2722 1875 m 2917 1875 l gs 0.95 setgray ef gr gs col0 s gr
+/Times-Roman ff 165.00 scf sf
+1830 2785 m
+gs 1 -1 sc (Definition) col0 sh gr
+/Times-Roman ff 120.00 scf sf
+2022 1338 m
+gs 1 -1 sc (X) col0 sh gr
+/Times-Roman ff 120.00 scf sf
+2022 2085 m
+gs 1 -1 sc (L) col0 sh gr
+/Times-Roman ff 165.00 scf sf
+2025 5025 m
+gs 1 -1 sc (Use) col0 sh gr
+% Arc
+gs n 3177.7 2812.0 1547.3 -25.9 25.9 arc
+gs col-1 s gr
+ gr
+
+% Arc
+gs n 9043.1 2812.0 3868.1 160.4 -160.4 arc
+gs col-1 s gr
+ gr
+
+% Arc
+gs n 2307.7 2812.0 3917.3 -19.4 19.4 arc
+gs col-1 s gr
+ gr
+
+% Ellipse
+n 5700 2812 1327 1327 0 360 DrawEllipse gs col-1 s gr
+
+% Polyline
+n 6677 3706 m 6685 3706 l gs col-1 s gr
+% Polyline
+n 6675 1912 m 6675 3712 l gs col-1 s gr
+% Polyline
+n 4368 2806 m 6675 2806 l gs col-1 s gr
+% Arc
+gs n 563.2 3905.0 966.8 -25.8 25.8 arc
+gs col-1 s gr
+ gr
+
+% Arc
+gs n 23.7 3905.0 2440.3 -19.4 19.4 arc
+gs col-1 s gr
+ gr
+
+% Arc
+gs n 4217.4 3905.0 2407.4 160.4 -160.4 arc
+gs col-1 s gr
+ gr
+
+% Ellipse
+n 2137 3905 826 826 0 360 DrawEllipse gs col-1 s gr
+
+% Polyline
+n 2743 4461 m 2751 4461 l gs col-1 s gr
+% Ellipse
+n 2115 1665 826 826 0 360 DrawEllipse gs col-1 s gr
+
+% Polyline
+n 2721 2221 m 2729 2221 l gs col-1 s gr
+% Polyline
+n 2722 1105 m 2722 2225 l gs col-1 s gr
+% Polyline
+n 1286 1665 m 2722 1665 l gs col-1 s gr
+$F2psEnd
+rs
diff --git a/lib/tools/doc/src/venn2.fig b/lib/tools/doc/src/venn2.fig
new file mode 100644
index 0000000000..3694c12f0c
--- /dev/null
+++ b/lib/tools/doc/src/venn2.fig
@@ -0,0 +1,97 @@
+#FIG 3.2
+Portrait
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+6 3392 953 5034 3329
+6 3392 953 5034 2595
+6 3392 953 5034 2595
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 2652.489 1773.500 3518 1357 3613 1774 3518 2190
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 6306.956 1773.000 4028 2575 3891 1774 4028 971
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 2105.283 1773.000 4402 971 4538 1774 4402 2575
+1 1 0 1 -1 7 0 0 -1 0.000 1 0.0000 4214 1774 820 821 4214 1774 3659 1171
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 1
+ 4821 2325
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 4816 1217 4816 2329
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 2
+ 3392 1769 4816 1769
+2 1 0 1 0 0 100 0 1 0.000 0 0 -1 0 0 2
+ 4816 1982 5008 1982
+-6
+2 3 0 0 0 0 101 0 5 0.000 0 0 -1 0 0 36
+ 4026 977 4011 1025 3996 1072 3981 1120 3966 1177 3954 1225
+ 3944 1272 3929 1327 3919 1412 3909 1477 3899 1540 3894 1592
+ 3894 1642 3891 1697 3889 1742 3889 1770 3394 1767 3396 1717
+ 3399 1665 3409 1610 3424 1555 3439 1502 3464 1440 3489 1390
+ 3516 1340 3551 1292 3584 1250 3631 1200 3679 1150 3731 1110
+ 3801 1065 3869 1030 3931 1005 3986 982 4009 980 4026 977
+-6
+4 0 0 101 0 0 11 0.0000 4 105 525 3965 3044 X - XU\001
+4 0 0 101 0 0 11 0.0000 4 150 1110 3688 3299 exports_not_used\001
+-6
+6 5850 938 7560 3329
+6 5884 938 7526 2580
+6 5884 938 7526 2580
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 5144.489 1758.500 6010 1342 6105 1759 6010 2175
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 8798.956 1758.000 6520 2560 6383 1759 6520 956
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 4597.283 1758.000 6894 956 7030 1759 6894 2560
+1 1 0 1 -1 7 0 0 -1 0.000 1 0.0000 6706 1759 820 821 6706 1759 6151 1156
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 1
+ 7313 2310
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 7308 1202 7308 2314
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 2
+ 5884 1754 7308 1754
+2 1 0 1 0 0 100 0 1 0.000 0 0 -1 0 0 2
+ 7308 1967 7500 1967
+-6
+2 3 0 0 0 0 101 0 5 0.000 0 0 -1 0 0 22
+ 6107 1757 6104 1802 6099 1855 6094 1902 6084 1960 6072 2010
+ 6062 2052 6049 2092 6032 2122 6019 2160 6007 2180 5984 2140
+ 5962 2095 5944 2057 5929 2007 5909 1947 5899 1892 5892 1835
+ 5889 1800 5889 1775 5889 1755 6107 1757
+2 3 0 0 0 0 101 0 5 0.000 0 0 -1 0 0 32
+ 7309 1757 7309 2315 7287 2340 7259 2365 7234 2390 7199 2412
+ 7164 2440 7124 2465 7092 2482 7054 2502 7014 2520 6974 2535
+ 6934 2547 6897 2557 6909 2510 6924 2457 6942 2407 6954 2357
+ 6967 2297 6979 2247 6992 2192 6999 2142 7009 2095 7012 2045
+ 7019 1990 7022 1945 7027 1900 7029 1855 7029 1805 7032 1765
+ 7029 1752 7309 1757
+-6
+4 0 0 101 0 0 11 0.0000 4 135 1470 6000 3014 L * (UU + (XU - LU))\001
+4 0 0 101 0 0 11 0.0000 4 150 1800 5850 3299 locals_not_used (simplified)\001
+-6
+6 900 900 2550 3600
+6 900 900 2550 2625
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 160.489 1780.500 1026 1364 1121 1781 1026 2197
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 3814.956 1780.000 1536 2582 1399 1781 1536 978
+5 1 0 1 -1 7 0 0 -1 0.000 0 0 0 0 -386.717 1780.000 1910 978 2046 1781 1910 2582
+1 1 0 1 -1 7 0 0 -1 0.000 1 0.0000 1722 1781 820 821 1722 1781 1167 1178
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 1
+ 2329 2332
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2324 1224 2324 2336
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 7 0 0 2
+ 900 1776 2324 1776
+2 1 0 1 0 0 100 0 1 0.000 0 0 -1 0 0 2
+ 2324 1989 2516 1989
+-6
+2 3 0 0 0 0 101 0 5 0.000 0 0 -1 0 0 27
+ 1395 1777 1400 1857 1405 1935 1407 2010 1417 2070 1425 2137
+ 1440 2215 1455 2297 1470 2365 1490 2437 1510 2495 1527 2547
+ 1535 2580 1600 2595 1672 2605 1772 2602 1865 2595 1947 2572
+ 2005 2555 2075 2525 2150 2482 2207 2442 2260 2400 2295 2367
+ 2325 2332 2325 1775 1395 1777
+2 3 0 0 0 0 101 0 5 0.000 0 0 -1 0 0 16
+ 2330 1222 2365 1265 2402 1317 2437 1382 2477 1455 2500 1517
+ 2520 1585 2532 1645 2540 1712 2542 1780 2540 1842 2535 1907
+ 2527 1957 2517 1990 2325 1987 2330 1222
+4 0 0 101 0 0 11 0.0000 4 105 780 1331 3044 XU - X - B\001
+4 0 0 101 0 0 11 0.0000 4 150 1260 1113 3314 undefined_functions\001
+4 0 0 100 0 0 10 0.0000 4 135 1005 1275 3525 (modules mode)\001
+-6
diff --git a/lib/tools/doc/src/venn2.gif b/lib/tools/doc/src/venn2.gif
new file mode 100644
index 0000000000..4cfea24646
--- /dev/null
+++ b/lib/tools/doc/src/venn2.gif
Binary files differ
diff --git a/lib/tools/doc/src/venn2.ps b/lib/tools/doc/src/venn2.ps
new file mode 100644
index 0000000000..198ccf285c
--- /dev/null
+++ b/lib/tools/doc/src/venn2.ps
@@ -0,0 +1,284 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: venn2b.eps
+%%Creator: fig2dev Version 3.2.3 Patchlevel
+%%CreationDate: Tue Oct 9 11:12:20 2001
+%%For: hasse@ulmo2 (Hans Bolinder)
+%%BoundingBox: 0 0 409 157
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 157 moveto 0 0 lineto 409 0 lineto 409 157 lineto closepath clip newpath
+% Fill background color
+0 0 moveto 409 0 lineto 409 157 lineto 0 157 lineto
+closepath 1.00 1.00 1.00 setrgbcolor fill
+
+-53.0 212.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/reencdict 12 dict def /ReEncode { reencdict begin
+/newcodesandnames exch def /newfontname exch def /basefontname exch def
+/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
+basefontdict { exch dup /FID ne { dup /Encoding eq
+{ exch dup length array copy newfont 3 1 roll put }
+{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
+newfont /FontName newfontname put newcodesandnames aload pop
+128 1 255 { newfont /Encoding get exch /.notdef put } for
+newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
+newfontname newfont definefont pop end } def
+/isovec [
+8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
+8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
+8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
+8#220 /dotlessi 8#230 /oe 8#231 /OE
+8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
+8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
+8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
+8#255 /hypen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
+8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
+8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
+8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
+8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
+8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
+8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
+8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
+8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
+8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
+8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
+8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
+8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
+8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
+8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
+8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
+8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
+8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
+8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
+/Times-Roman /Times-Roman-iso isovec ReEncode
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+%%Page: 1 1
+10 setmiterlimit
+ 0.06000 0.06000 sc
+% Polyline
+n 4026 977 m 4011 1025 l 3996 1072 l 3981 1120 l 3966 1177 l 3954 1225 l
+ 3944 1272 l 3929 1327 l 3919 1412 l 3909 1477 l 3899 1540 l
+ 3894 1592 l 3894 1642 l 3891 1697 l 3889 1742 l 3889 1770 l
+ 3394 1767 l 3396 1717 l 3399 1665 l 3409 1610 l 3424 1555 l
+ 3439 1502 l 3464 1440 l 3489 1390 l 3516 1340 l 3551 1292 l
+ 3584 1250 l 3631 1200 l 3679 1150 l 3731 1110 l 3801 1065 l
+ 3869 1030 l 3931 1005 l 3986 982 l 4009 980 l
+ cp gs 0.75 setgray ef gr
+/Times-Roman-iso ff 165.00 scf sf
+3965 3044 m
+gs 1 -1 sc (X - XU) col0 sh gr
+/Times-Roman-iso ff 165.00 scf sf
+3688 3299 m
+gs 1 -1 sc (exports_not_used) col0 sh gr
+% Polyline
+n 6107 1757 m 6104 1802 l 6099 1855 l 6094 1902 l 6084 1960 l 6072 2010 l
+ 6062 2052 l 6049 2092 l 6032 2122 l 6019 2160 l 6007 2180 l
+ 5984 2140 l 5962 2095 l 5944 2057 l 5929 2007 l 5909 1947 l
+ 5899 1892 l 5892 1835 l 5889 1800 l 5889 1775 l 5889 1755 l
+
+ cp gs 0.75 setgray ef gr
+% Polyline
+n 7309 1757 m 7309 2315 l 7287 2340 l 7259 2365 l 7234 2390 l 7199 2412 l
+ 7164 2440 l 7124 2465 l 7092 2482 l 7054 2502 l 7014 2520 l
+ 6974 2535 l 6934 2547 l 6897 2557 l 6909 2510 l 6924 2457 l
+ 6942 2407 l 6954 2357 l 6967 2297 l 6979 2247 l 6992 2192 l
+ 6999 2142 l 7009 2095 l 7012 2045 l 7019 1990 l 7022 1945 l
+ 7027 1900 l 7029 1855 l 7029 1805 l 7032 1765 l 7029 1752 l
+
+ cp gs 0.75 setgray ef gr
+/Times-Roman-iso ff 165.00 scf sf
+6000 3014 m
+gs 1 -1 sc (L * \(UU + \(XU - LU\)\)) col0 sh gr
+/Times-Roman-iso ff 165.00 scf sf
+5850 3299 m
+gs 1 -1 sc (locals_not_used \(simplified\)) col0 sh gr
+% Polyline
+n 1395 1777 m 1400 1857 l 1405 1935 l 1407 2010 l 1417 2070 l 1425 2137 l
+ 1440 2215 l 1455 2297 l 1470 2365 l 1490 2437 l 1510 2495 l
+ 1527 2547 l 1535 2580 l 1600 2595 l 1672 2605 l 1772 2602 l
+ 1865 2595 l 1947 2572 l 2005 2555 l 2075 2525 l 2150 2482 l
+ 2207 2442 l 2260 2400 l 2295 2367 l 2325 2332 l 2325 1775 l
+
+ cp gs 0.75 setgray ef gr
+% Polyline
+n 2330 1222 m 2365 1265 l 2402 1317 l 2437 1382 l 2477 1455 l 2500 1517 l
+ 2520 1585 l 2532 1645 l 2540 1712 l 2542 1780 l 2540 1842 l
+ 2535 1907 l 2527 1957 l 2517 1990 l 2325 1987 l
+ cp gs 0.75 setgray ef gr
+/Times-Roman-iso ff 165.00 scf sf
+1331 3044 m
+gs 1 -1 sc (XU - X - B) col0 sh gr
+/Times-Roman-iso ff 165.00 scf sf
+1113 3314 m
+gs 1 -1 sc (undefined_functions) col0 sh gr
+% Polyline
+7.500 slw
+n 4816 1982 m
+ 5008 1982 l gs 0.95 setgray ef gr gs col0 s gr
+% Polyline
+n 7308 1967 m
+ 7500 1967 l gs 0.95 setgray ef gr gs col0 s gr
+% Polyline
+n 2324 1989 m
+ 2516 1989 l gs 0.95 setgray ef gr gs col0 s gr
+/Times-Roman-iso ff 150.00 scf sf
+1275 3525 m
+gs 1 -1 sc (\(modules mode\)) col0 sh gr
+% Arc
+n 2652.5 1773.5 960.5 -25.7 25.7 arc
+gs col-1 s gr
+
+% Arc
+n 6307.0 1773.0 2416.0 160.6 -160.6 arc
+gs col-1 s gr
+
+% Arc
+n 2105.3 1773.0 2432.7 -19.2 19.2 arc
+gs col-1 s gr
+
+% Ellipse
+n 4214 1774 820 821 0 360 DrawEllipse gs col-1 s gr
+
+% Polyline
+n 4817 2325 m 4825 2325 l gs col-1 s gr
+% Polyline
+n 4816 1217 m
+ 4816 2329 l gs col-1 s gr
+% Polyline
+n 3392 1769 m
+ 4816 1769 l gs col-1 s gr
+% Arc
+n 5144.5 1758.5 960.5 -25.7 25.7 arc
+gs col-1 s gr
+
+% Arc
+n 8799.0 1758.0 2416.0 160.6 -160.6 arc
+gs col-1 s gr
+
+% Arc
+n 4597.3 1758.0 2432.7 -19.2 19.2 arc
+gs col-1 s gr
+
+% Ellipse
+n 6706 1759 820 821 0 360 DrawEllipse gs col-1 s gr
+
+% Polyline
+n 7309 2310 m 7317 2310 l gs col-1 s gr
+% Polyline
+n 7308 1202 m
+ 7308 2314 l gs col-1 s gr
+% Polyline
+n 5884 1754 m
+ 7308 1754 l gs col-1 s gr
+% Arc
+n 160.5 1780.5 960.5 -25.7 25.7 arc
+gs col-1 s gr
+
+% Arc
+n 3815.0 1780.0 2416.0 160.6 -160.6 arc
+gs col-1 s gr
+
+% Arc
+n -386.7 1780.0 2432.7 -19.2 19.2 arc
+gs col-1 s gr
+
+% Ellipse
+n 1722 1781 820 821 0 360 DrawEllipse gs col-1 s gr
+
+% Polyline
+n 2325 2332 m 2333 2332 l gs col-1 s gr
+% Polyline
+n 2324 1224 m
+ 2324 2336 l gs col-1 s gr
+% Polyline
+n 900 1776 m
+ 2324 1776 l gs col-1 s gr
+$F2psEnd
+rs
diff --git a/lib/tools/doc/src/warning.gif b/lib/tools/doc/src/warning.gif
new file mode 100644
index 0000000000..96af52360e
--- /dev/null
+++ b/lib/tools/doc/src/warning.gif
Binary files differ
diff --git a/lib/tools/doc/src/xref.xml b/lib/tools/doc/src/xref.xml
new file mode 100644
index 0000000000..6fff68fe9f
--- /dev/null
+++ b/lib/tools/doc/src/xref.xml
@@ -0,0 +1,1554 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE erlref SYSTEM "erlref.dtd">
+
+<erlref>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>xref</title>
+ <prepared>Hans Bolinder</prepared>
+ <responsible>nobody</responsible>
+ <docno></docno>
+ <approved>nobody</approved>
+ <checked>no</checked>
+ <date>2000-08-15</date>
+ <rev>PA1</rev>
+ <file>xref.sgml</file>
+ </header>
+ <module>xref</module>
+ <modulesummary>A Cross Reference Tool for analyzing dependencies between functions, modules, applications and releases.</modulesummary>
+ <description>
+ <p>Xref is a cross reference tool that can be used for finding
+ dependencies between functions, modules, applications and
+ releases.
+ </p>
+ <p>Calls between functions are either <marker id="local_call"></marker>
+<em>local calls</em> like <c>f()</c>, or <marker id="external_call"></marker>
+<em>external calls</em> like
+ <c>m:f()</c>. <marker id="module_data"></marker>
+<em>Module data</em>,
+ which are extracted from BEAM files, include local functions,
+ exported functions, local calls and external calls. By default,
+ calls to built-in functions (<term id="BIF"></term>) are ignored, but
+ if the option <c>builtins</c>, accepted by some of this
+ module's functions, is set to <c>true</c>, calls to BIFs
+ are included as well. It is the analyzing OTP version that
+ decides what functions are BIFs. Functional objects are assumed
+ to be called where they are created (and nowhere else). <marker id="unresolved_call"></marker>
+<em>Unresolved calls</em> are calls to
+ <c>apply</c> or <c>spawn</c> with variable module, variable
+ function, or variable arguments. Examples are <c>M:F(a)</c>,
+ <c>apply(M,&nbsp;f,&nbsp;[a])</c>, and
+ <c>spawn(m,&nbsp;f(),&nbsp;Args)</c>. Unresolved calls are
+ represented by calls where variable modules have been replaced
+ with the atom <c>'$M_EXPR'</c>, variable functions have been
+ replaced with the atom <c>'$F_EXPR'</c>, and variable number of
+ arguments have been replaced with the number <c>-1</c>. The
+ above mentioned examples are represented by calls to
+ <c>'$M_EXPR':'$F_EXPR'/1</c>, <c>'$M_EXPR':f/1</c>, and
+ <c>m:'$F_EXPR'/-1</c>. The unresolved calls are a subset of the
+ external calls.
+ </p>
+ <warning>
+ <p>Unresolved calls make module data incomplete, which
+ implies that the results of analyses may be invalid.</p>
+ </warning>
+ <p><em>Applications</em> are collections of modules. The
+ modules' BEAM files are located in the <c>ebin</c>
+ subdirectory of the application directory. The name of the
+ application directory determines the name and version of the
+ application.
+ <em>Releases</em> are collections of applications
+ located in the <c>lib</c> subdirectory of the release directory.
+ There is more to read about applications and releases in the
+ Design Principles book.
+ </p>
+ <p> <marker id="xref_server"></marker>
+<em>Xref servers</em> are identified
+ by names, supplied when creating new servers. Each Xref server
+ holds a set of releases, a set of applications, and a set of
+ modules with module data. Xref servers are independent of each
+ other, and all analyses are evaluated in the context of one
+ single Xref server (exceptions are the functions <c>m/1</c> and
+ <c>d/1</c> which do not use servers at all). The <marker id="mode"></marker>
+<em>mode</em> of an Xref server determines what module
+ data are extracted from BEAM files as modules are added to the
+ server. Starting with R7, BEAM files compiled with the option
+ <c>debug_info</c> contain so called <marker id="debug_info"></marker>
+debug information, which is an abstract
+ representation of the code. In <c>functions</c> mode, which is
+ the default mode, function calls and line numbers are extracted
+ from debug information. In <c>modules</c> mode, debug
+ information is ignored if present, but dependencies between
+ modules are extracted from other parts of the BEAM files. The
+ <c>modules</c> mode is significantly less time and space
+ consuming than the <c>functions</c> mode, but the analyses that
+ can be done are limited.
+ </p>
+ <p>An <marker id="analyzed_module"></marker>
+<em>analyzed module</em> is a
+ module that has been added to an Xref server together with its
+ module data.
+ A <marker id="library_module"></marker>
+<em>library module</em> is a
+ module located in some directory mentioned in the <marker id="library_path"></marker>
+<em>library path</em>.
+ A library module is said to be used if some of its exported
+ functions are used by some analyzed module.
+ An <marker id="unknown_module"></marker>
+<em>unknown module</em> is a
+ module that is neither an analyzed module nor a library module,
+ but whose exported functions are used by some analyzed module.
+ An <marker id="unknown_function"></marker>
+<em>unknown function</em> is a
+ used function that is neither local or exported by any
+ analyzed module nor exported by any library module.
+ An <marker id="undefined_function"></marker>
+<em>undefined function</em> is an externally used function that
+ is not exported by any analyzed module or library module. With
+ this notion, a local function can be an undefined function, namely
+ if it is externally used from some module. All unknown functions
+ are also undefined functions; there is a <seealso marker="xref_chapter#venn2">figure</seealso> in the
+ User's Guide that illustrates this relationship.
+ </p>
+ <p>Starting with R9C, the module attribute tag <c>deprecated</c>
+ can be used to inform Xref about <marker id="deprecated_function"></marker>
+<em>deprecated functions</em> and
+ optionally when functions are planned to be removed. A few
+ examples show the idea:
+ </p>
+ <taglist>
+ <tag>-deprecated({f,1}).</tag>
+ <item>The exported function <c>f/1</c> is deprecated. Nothing is
+ said whether <c>f/1</c> will be removed or not.</item>
+ <tag>-deprecated({f,'_'}).</tag>
+ <item>All exported functions <c>f/0</c>, <c>f/1</c> and so on are
+ deprecated.</item>
+ <tag>-deprecated(module).</tag>
+ <item>All exported functions in the module are deprecated.
+ Equivalent to <c>-deprecated({'_','_'}).</c>.</item>
+ <tag>-deprecated([{g,1,next_version}]).</tag>
+ <item>The function <c>g/1</c> is deprecated and will be
+ removed in next version.</item>
+ <tag>-deprecated([{g,2,next_major_release}]).</tag>
+ <item>The function <c>g/2</c> is deprecated and will be
+ removed in next major release.</item>
+ <tag>-deprecated([{g,3,eventually}]).</tag>
+ <item>The function <c>g/3</c> is deprecated and will
+ eventually be removed.</item>
+ <tag>-deprecated({'_','_',eventually}).</tag>
+ <item>All exported functions in the module are deprecated and
+ will eventually be removed.</item>
+ </taglist>
+ <p>Before any analysis can take place, module data must be <em>set up</em>. For instance, the cross reference and the unknown
+ functions are computed when all module data are known. The
+ functions that need complete data (<c>analyze</c>, <c>q</c>,
+ <c>variables</c>) take care of setting up data automatically.
+ Module data need to be set up (again) after calls to any of the
+ <c>add</c>, <c>replace</c>, <c>remove</c>,
+ <c>set_library_path</c> or <c>update</c> functions.
+ </p>
+ <p>The result of setting up module data is the <marker id="call_graph"></marker>
+<em>Call Graph</em>. A (directed) graph
+ consists of a set of vertices and a set of (directed) edges. The
+ edges represent <marker id="call"></marker>
+<em>calls</em> (From,&nbsp;To)
+ between functions, modules, applications or releases. From is
+ said to call To, and To is said to be used by From. The vertices
+ of the Call Graph are the functions of all module data: local
+ and exported functions of analyzed modules; used BIFs; used
+ exported functions of library modules; and unknown functions.
+ The functions <c>module_info/0,1</c> added by the compiler are
+ included among the exported functions, but only when called from
+ some module. The edges are the function calls of all module
+ data. A consequence of the edges being a set is that there is
+ only one edge if a function is locally or externally used
+ several times on one and the same line of code.
+ </p>
+ <p>The Call Graph is <marker id="representation"></marker>
+represented by
+ Erlang terms (the sets are lists), which is suitable for many
+ analyses. But for analyses that look at chains of calls, a list
+ representation is much too
+ slow. Instead the representation offered by the <c>digraph</c>
+ module is used. The translation of the list representation of
+ the Call Graph - or a subgraph thereof - to the <c>digraph</c>
+ representation does not
+ come for free, so the language used for expressing queries to be
+ described below has a special operator for this task and a
+ possibility to save the <c>digraph</c> representation for
+ subsequent analyses.
+ </p>
+ <p>In addition to the Call Graph there is a graph called the
+ <marker id="inter_call_graph"></marker>
+<em>Inter Call Graph</em>. This is
+ a graph of calls (From,&nbsp;To) such that there is a chain of
+ calls from From to To in the Call Graph, and every From and To
+ is an exported function or an unused local function.
+ The vertices are the same as for the Call Graph.
+ </p>
+ <p>Calls between modules, applications and releases are also
+ directed graphs. The <marker id="type"></marker>
+<em>types</em>
+ of the vertices and edges of these graphs are (ranging from the
+ most special to the most general):
+ <c>Fun</c> for functions; <c>Mod</c> for modules;
+ <c>App</c> for applications; and <c>Rel</c> for releases.
+ The following paragraphs will describe the different constructs
+ of the language used for selecting and analyzing parts of the
+ graphs, beginning with the <marker id="constants"></marker>
+<em>constants</em>:
+ </p>
+ <list type="bulleted">
+ <item>Expression ::= Constants</item>
+ <item>Constants ::= Consts | Consts <c>:</c> Type | RegExpr</item>
+ <item>Consts ::= Constant | <c>[</c>Constant<c>,</c>&nbsp;...<c>]</c>
+ | <c>{</c>Constant<c>,</c>&nbsp;...<c>}</c></item>
+ <item>Constant ::= Call | Const</item>
+ <item>Call ::= FunSpec&nbsp;<c>-></c>&nbsp;FunSpec
+ | <c>{</c>MFA<c>,</c>&nbsp;MFA<c>}</c>
+ | AtomConst&nbsp;<c>-></c>&nbsp;AtomConst
+ | <c>{</c>AtomConst<c>,</c>&nbsp;AtomConst<c>}</c></item>
+ <item>Const ::= AtomConst | FunSpec | MFA</item>
+ <item>AtomConst ::= Application | Module | Release</item>
+ <item>FunSpec ::= Module <c>:</c> Function <c>/</c> Arity</item>
+ <item>MFA ::=
+ <c>{</c>Module<c>,</c>&nbsp;Function<c>,</c>&nbsp;Arity<c>}</c></item>
+ <item>RegExpr ::= RegString <c>:</c> Type
+ | RegFunc
+ | RegFunc <c>:</c> Type</item>
+ <item>RegFunc ::= RegModule <c>:</c> RegFunction <c>/</c> RegArity</item>
+ <item>RegModule ::= RegAtom</item>
+ <item>RegFunction ::= RegAtom</item>
+ <item>RegArity ::= RegString | Number | <c>_</c> | <c>-1</c></item>
+ <item>RegAtom ::= RegString | Atom | <c>_</c></item>
+ <item>RegString ::= - a regular expression, as described in the
+ <c>regexp</c> module, enclosed in double quotes -</item>
+ <item>Type ::= <c>Fun</c> | <c>Mod</c> | <c>App</c> | <c>Rel</c></item>
+ <item>Function ::= Atom</item>
+ <item>Application ::= Atom</item>
+ <item>Module ::= Atom</item>
+ <item>Release ::= Atom</item>
+ <item>Arity ::= Number | <c>-1</c></item>
+ <item>Atom ::= - same as Erlang atoms -</item>
+ <item>Number ::= - same as non-negative Erlang integers -</item>
+ </list>
+ <p>Examples of constants are: <c>kernel</c>, <c>kernel->stdlib</c>,
+ <c>[kernel, sasl]</c>, <c>[pg -> mnesia, {tv, mnesia}] : Mod</c>.
+ It is an error if an instance of <c>Const</c> does not match any
+ vertex of any graph.
+ If there are more than one vertex matching an untyped instance
+ of <c>AtomConst</c>, then the one of the most general type is
+ chosen.
+ A list of constants is interpreted as a set of constants, all of
+ the same type.
+ A tuple of constants constitute a chain of calls (which may,
+ but does not have to, correspond to an actual chain of calls of
+ some graph).
+ Assigning a type to a list or tuple of <c>Constant</c> is
+ equivalent to assigning the type to each <c>Constant</c>.
+ </p>
+ <p> <marker id="regexp"></marker>
+<em>Regular expressions</em> are used as a
+ means to select some of the vertices of a graph.
+ A <c>RegExpr</c> consisting of a <c>RegString</c> and a type -
+ an example is <c>"xref_.*" : Mod</c> - is interpreted as those
+ modules (or applications or releases, depending on the type)
+ that match the expression.
+ Similarly, a <c>RegFunc</c> is interpreted as those vertices
+ of the Call Graph that match the expression.
+ An example is <c>"xref_.*":"add_.*"/"(2|3)"</c>, which matches
+ all <c>add</c> functions of arity two or three of any of the
+ xref modules.
+ Another example, one that matches all functions of arity 10 or
+ more: <c>_:_/"[1-9].+"</c>. Here <c>_</c> is an abbreviation for
+ <c>".*"</c>, that is, the regular expression that matches
+ anything.
+ </p>
+ <p>The syntax of <marker id="variable"></marker>
+<em>variables</em> is
+ simple:
+ </p>
+ <list type="bulleted">
+ <item>Expression ::= Variable</item>
+ <item>Variable ::= - same as Erlang variables -</item>
+ </list>
+ <p>There are two kinds of variables: predefined variables and user
+ variables.
+ <marker id="predefined_variable"></marker>
+<em>Predefined variables</em>
+ hold set up module data, and cannot be assigned to but only used
+ in queries.
+ <marker id="user_variable"></marker>
+<em>User variables</em> on the other
+ hand can be assigned to, and are typically used for
+ temporary results while evaluating a query, and for keeping
+ results of queries for use in subsequent queries.
+ The predefined variables are (variables marked with (*) are
+ available in <c>functions</c> mode only):
+ </p>
+ <taglist>
+ <tag><c>E</c></tag>
+ <item>Call Graph Edges (*).</item>
+ <tag><c>V</c></tag>
+ <item>Call Graph Vertices (*).
+ </item>
+ <tag><c>M</c></tag>
+ <item>Modules. All modules: analyzed modules, used library
+ modules, and unknown modules.</item>
+ <tag><c>A</c></tag>
+ <item>Applications.</item>
+ <tag><c>R</c></tag>
+ <item>Releases.
+ </item>
+ <tag><c>ME</c></tag>
+ <item>Module Edges. All module calls.</item>
+ <tag><c>AE</c></tag>
+ <item>Application Edges. All application calls. </item>
+ <tag><c>RE</c></tag>
+ <item>Release Edges. All release calls.
+ </item>
+ <tag><c>L</c></tag>
+ <item>Local Functions (*). All local functions of analyzed modules.</item>
+ <tag><c>X</c></tag>
+ <item>Exported Functions. All exported functions of analyzed
+ modules and all used exported functions of library modules.</item>
+ <tag><c>F</c></tag>
+ <item>Functions (*).</item>
+ <tag><c>B</c></tag>
+ <item>Used BIFs. <c>B</c> is empty if <c>builtins</c> is
+ <c>false</c> for all analyzed modules.</item>
+ <tag><c>U</c></tag>
+ <item>Unknown Functions.</item>
+ <tag><c>UU</c></tag>
+ <item>Unused Functions (*). All local and exported functions of
+ analyzed modules that have not been used. </item>
+ <tag><c>XU</c></tag>
+ <item>Externally Used Functions. Functions of all modules -
+ including local functions - that have been used in some
+ external call.</item>
+ <tag><c>LU</c></tag>
+ <item>Locally Used Functions (*). Functions of all modules that have
+ been used in some local call.
+ </item>
+ <tag><c>LC</c></tag>
+ <item>Local Calls (*).</item>
+ <tag><c>XC</c></tag>
+ <item>External Calls (*).
+ </item>
+ <tag><c>AM</c></tag>
+ <item>Analyzed Modules.</item>
+ <tag><c>UM</c></tag>
+ <item>Unknown Modules.</item>
+ <tag><c>LM</c></tag>
+ <item>Used Library Modules.
+ </item>
+ <tag><c>UC</c></tag>
+ <item>Unresolved Calls. Empty in <c>modules</c> mode.
+ </item>
+ <tag><c>EE</c></tag>
+ <item>Inter Call Graph Edges (*).
+ </item>
+ <tag><c>DF</c></tag>
+ <item>Deprecated Functions. All deprecated exported
+ functions and all used deprecated BIFs.</item>
+ <tag><c>DF_1</c></tag>
+ <item>Deprecated Functions. All deprecated functions
+ to be removed in next version.</item>
+ <tag><c>DF_2</c></tag>
+ <item>Deprecated Functions. All deprecated functions
+ to be removed in next version or next major release.</item>
+ <tag><c>DF_3</c></tag>
+ <item>Deprecated Functions. All deprecated functions to be
+ removed in next version, next major release, or later.</item>
+ </taglist>
+ <p>These are a few <marker id="simple_facts"></marker>
+facts about the
+ predefined variables (the set operators <c>+</c> (union) and
+ <c>-</c> (difference) as well as the cast operator
+ <c>(</c>Type<c>)</c> are described below):
+ </p>
+ <list type="bulleted">
+ <item><c>F</c> is equal to <c>L + X</c>.</item>
+ <item><c>V</c> is equal to <c>X + L + B + U</c>, where <c>X</c>,
+ <c>L</c>, <c>B</c> and <c>U</c> are pairwise disjoint (that
+ is, have no elements in common).</item>
+ <item><c>UU</c> is equal to <c>V - (XU + LU)</c>, where
+ <c>LU</c> and <c>XU</c> may have elements in common. Put in
+ another way:</item>
+ <item><c>V</c> is equal to <c>UU + XU + LU</c>.</item>
+ <item><c>E</c> is equal to <c>LC + XC</c>. Note that <c>LC</c>
+ and <c>XC</c> may have elements in common, namely if some
+ function is locally and externally used from one and the same
+ function.</item>
+ <item><c>U</c> is a subset of <c>XU</c>.</item>
+ <item><c>B</c> is a subset of <c>XU</c>.</item>
+ <item><c>LU</c> is equal to <c>range LC</c>.</item>
+ <item><c>XU</c> is equal to <c>range XC</c>.</item>
+ <item><c>LU</c> is a subset of <c>F</c>.</item>
+ <item><c>UU</c> is a subset of <c>F</c>. </item>
+ <item><c>range UC</c> is a subset of <c>U</c>.</item>
+ <item><c>M</c> is equal to <c>AM + LM + UM</c>, where <c>AM</c>,
+ <c>LM</c> and <c>UM</c> are pairwise disjoint. </item>
+ <item><c>ME</c> is equal to <c>(Mod) E</c>.</item>
+ <item><c>AE</c> is equal to <c>(App) E</c>.</item>
+ <item><c>RE</c> is equal to <c>(Rel) E</c>.</item>
+ <item><c>(Mod) V</c> is a subset of <c>M</c>. Equality holds
+ if all analyzed modules have some local, exported, or unknown
+ function.</item>
+ <item><c>(App) M</c> is a subset of <c>A</c>. Equality holds
+ if all applications have some module.</item>
+ <item><c>(Rel) A</c> is a subset of <c>R</c>. Equality holds
+ if all releases have some application.</item>
+ <item><c>DF_1</c> is a subset of <c>DF_2</c>.</item>
+ <item><c>DF_2</c> is a subset of <c>DF_3</c>.</item>
+ <item><c>DF_3</c> is a subset of <c>DF</c>.</item>
+ <item><c>DF</c> is a subset of <c>X + B</c>.</item>
+ </list>
+ <p>An important notion is that of <marker id="conversion"></marker>
+<em>conversion</em> of expressions. The syntax of
+ a cast expression is:
+ </p>
+ <list type="bulleted">
+ <item>Expression ::= <c>(</c> Type <c>)</c> Expression</item>
+ </list>
+ <p>The interpretation of the cast operator depends on the named
+ type <c>Type</c>, the type of <c>Expression</c>, and the
+ structure of the elements of the interpretation of <c>Expression</c>.
+ If the named type is equal to the
+ expression type, no conversion is done. Otherwise, the
+ conversion is done one step at a time;
+ <c>(Fun)&nbsp;(App)&nbsp;RE</c>, for instance, is equivalent to
+ <c>(Fun)&nbsp;(Mod)&nbsp;(App)&nbsp;RE</c>. Now assume that the
+ interpretation of <c>Expression</c> is a set of constants
+ (functions, modules, applications or releases). If the named
+ type is more general than the expression type, say <c>Mod</c>
+ and <c>Fun</c> respectively, then the interpretation of the cast
+ expression is the set of modules that have at least one
+ of their functions mentioned in the interpretation of the
+ expression. If the named
+ type is more special than the expression type, say <c>Fun</c>
+ and <c>Mod</c>, then the interpretation is the set of all the
+ functions of the modules (in <c>modules</c> mode, the conversion
+ is partial since the local functions are not known).
+ The conversions to and from applications and releases
+ work analogously. For instance, <c>(App) "xref_.*" : Mod</c>
+ returns all applications containing at least one module
+ such that <c>xref_</c> is a prefix of the module name.
+ </p>
+ <p>Now assume that the interpretation of <c>Expression</c> is a
+ set of calls. If the named type is more general than the
+ expression type, say <c>Mod</c> and <c>Fun</c> respectively,
+ then the interpretation of the cast expression is the set of
+ calls (M1,&nbsp;M2) such that the interpretation of the
+ expression contains a call from some function
+ of M1 to some function of M2. If the named type is more special
+ than the expression type, say <c>Fun</c> and <c>Mod</c>, then
+ the interpretation is the set of all function calls
+ (F1,&nbsp;F2) such that the interpretation of the expression
+ contains a call (M1,&nbsp;M2) and F1 is
+ a function of M1 and F2 is a function of M2 (in <c>modules</c>
+ mode, there are no functions calls, so a cast to <c>Fun</c>
+ always yields an empty set). Again, the conversions to and from
+ applications and releases work analogously.
+ </p>
+ <p>The interpretation of constants and variables are sets, and
+ those sets can be used as the basis for forming new sets by the
+ application of <marker id="set_operator"></marker>
+<em>set operators</em>.
+ The syntax:
+ </p>
+ <list type="bulleted">
+ <item>Expression ::= Expression BinarySetOp Expression</item>
+ <item>BinarySetOp ::= <c>+</c> | <c>*</c> | <c>-</c></item>
+ </list>
+ <p><c>+</c>, <c>*</c> and <c>-</c> are interpreted as union,
+ intersection and difference respectively: the union of two sets
+ contains the elements of both sets; the intersection of two sets
+ contains the elements common to both sets; and the difference of
+ two sets contains the elements of the first set that are not
+ members of the second set. The elements of the two sets must be
+ of the same structure; for instance, a function call cannot be
+ combined with a function. But if a cast operator can make the
+ elements compatible, then the more general elements are
+ converted to the less general element type. For instance,
+ <c>M&nbsp;+&nbsp;F</c> is equivalent to
+ <c>(Fun)&nbsp;M&nbsp;+&nbsp;F</c>, and <c>E&nbsp;-&nbsp;AE</c>
+ is equivalent to <c>E&nbsp;-&nbsp;(Fun)&nbsp;AE</c>. One more
+ example: <c>X * xref : Mod</c> is interpreted as the set of
+ functions exported by the module <c>xref</c>; <c>xref : Mod</c>
+ is converted to the more special type of <c>X</c> (<c>Fun</c>,
+ that is) yielding all functions of <c>xref</c>, and the
+ intersection with <c>X</c> (all functions exported by analyzed
+ modules and library modules) is interpreted as those functions
+ that are exported by some module <em>and</em> functions of
+ <c>xref</c>.
+ </p>
+ <p>There are also unary set operators:
+ </p>
+ <list type="bulleted">
+ <item>Expression ::= UnarySetOp Expression</item>
+ <item>UnarySetOp ::= <c>domain</c> | <c>range</c> | <c>strict</c></item>
+ </list>
+ <p>Recall that a call is a pair (From,&nbsp;To). <c>domain</c>
+ applied to a set of calls is interpreted as the set of all
+ vertices From, and <c>range</c> as the set of all vertices To.
+ The interpretation of the <c>strict</c> operator is the operand
+ with all calls on the form (A,&nbsp;A) removed.
+ </p>
+ <p>The interpretation of the <marker id="restriction"></marker>
+<em>restriction operators</em> is a
+ subset of the first operand, a set of calls. The second operand,
+ a set of vertices, is converted to the type of the first operand.
+ The syntax of the restriction operators:
+ </p>
+ <list type="bulleted">
+ <item>Expression ::= Expression RestrOp Expression</item>
+ <item>RestrOp ::= <c>|</c></item>
+ <item>RestrOp ::= <c>||</c></item>
+ <item>RestrOp ::= <c>|||</c></item>
+ </list>
+ <p>The interpretation in some detail for the three operators:
+ </p>
+ <taglist>
+ <tag><c>|</c></tag>
+ <item>The subset of calls from any of the vertices.</item>
+ <tag><c>||</c></tag>
+ <item>The subset of calls to any of the vertices.</item>
+ <tag><c>|||</c></tag>
+ <item>The subset of calls to and from any of the vertices.
+ For all sets of calls <c>CS</c> and all sets of vertices
+ <c>VS</c>, <c>CS&nbsp;|||&nbsp;VS&nbsp;</c> is equivalent to
+ <c>CS&nbsp;|&nbsp;VS&nbsp;*&nbsp;CS&nbsp;||&nbsp;VS</c>.</item>
+ </taglist>
+ <p> <marker id="graph_analyses"></marker>
+Two functions (modules,
+ applications, releases) belong to the same strongly connected
+ component if they call each other (in)directly. The
+ interpretation of the <c>components</c> operator is the set of
+ strongly connected components of a set of calls. The
+ <c>condensation</c> of a set of calls is a new set of calls
+ between the strongly connected components such that there is an
+ edge between two components if there is some constant of the first
+ component that calls some constant of the second component.
+ </p>
+ <p>The interpretation of the <c>of</c> operator is a chain of
+ calls of the second operand (a set of calls) that passes throw
+ all of the vertices of the first operand (a tuple of
+ constants), in the given order. The second operand
+ is converted to the type of the first operand.
+ For instance, the <c>of</c> operator can be used for finding out
+ whether a function calls another function indirectly, and the
+ chain of calls demonstrates how. The syntax of the graph
+ analyzing operators:
+ </p>
+ <list type="bulleted">
+ <item>Expression ::= Expression GraphOp Expression</item>
+ <item>GraphOp ::= <c>components</c> | <c>condensation</c> | <c>of</c></item>
+ </list>
+ <p>As was mentioned before, the graph analyses operate on
+ the <c>digraph</c> representation of graphs.
+ By default, the <c>digraph</c> representation is created when
+ needed (and deleted when no longer used), but it can also be
+ created explicitly by use of the <c>closure</c> operator:
+ </p>
+ <list type="bulleted">
+ <item>Expression ::= ClosureOp Expression</item>
+ <item>ClosureOp ::= <c>closure</c></item>
+ </list>
+ <p>The interpretation of the <c>closure</c> operator is the
+ transitive closure of the operand.
+ </p>
+ <p>The restriction operators are defined for closures as well;
+ <c>closure&nbsp;E&nbsp;|&nbsp;xref&nbsp;:&nbsp;Mod</c> is
+ interpreted as the direct or indirect function calls from the
+ <c>xref</c> module, while the interpretation of
+ <c>E&nbsp;|&nbsp;xref&nbsp;:&nbsp;Mod</c> is the set of direct
+ calls from <c>xref</c>.
+ If some graph is to be used in several graph analyses, it saves
+ time to assign the <c>digraph</c> representation of the graph
+ to a user variable,
+ and then make sure that every graph analysis operates on that
+ variable instead of the list representation of the graph.
+ </p>
+ <p>The lines where functions are defined (more precisely: where
+ the first clause begins) and the lines where functions are used
+ are available in <c>functions</c> mode. The line numbers refer
+ to the files where the functions are defined. This holds also for
+ files included with the <c>-include</c> and <c>-include_lib</c>
+ directives, which may result in functions defined apparently in
+ the same line. The <em>line operators</em> are used for assigning
+ line numbers to functions and for assigning sets of line numbers
+ to function calls.
+ The syntax is similar to the one of the cast operator:
+ </p>
+ <list type="bulleted">
+ <item>Expression ::= <c>(</c> LineOp<c>)</c> Expression</item>
+ <item>Expression ::= <c>(</c> XLineOp<c>)</c> Expression</item>
+ <item>LineOp ::= <c>Lin</c> | <c>ELin</c> | <c>LLin</c> | <c>XLin</c></item>
+ <item>XLineOp ::= <c>XXL</c></item>
+ </list>
+ <p>The interpretation of the <c>Lin</c> operator applied to a set
+ of functions assigns to each function the line number where the
+ function is defined. Unknown functions and functions of library
+ modules are assigned the number 0.
+ </p>
+ <p>The interpretation of some LineOp operator applied to a
+ set of function calls assigns to each call the set of line
+ numbers where the first function calls the second function. Not
+ all calls are assigned line numbers by all operators:
+ </p>
+ <list type="bulleted">
+ <item>the <c>Lin</c> operator is defined for Call Graph Edges;</item>
+ <item>the <c>LLin</c> operator is defined for Local Calls.</item>
+ <item>the <c>XLin</c> operator is defined for External Calls.</item>
+ <item>the <c>ELin</c> operator is defined for Inter Call Graph Edges.</item>
+ </list>
+ <p>The <c>Lin</c> (<c>LLin</c>, <c>XLin</c>) operator assigns
+ the lines where calls (local calls, external calls) are made.
+ The <c>ELin</c> operator assigns to each call (From,&nbsp;To),
+ for which it is defined, every line L such that there is
+ a chain of calls from From to To beginning with a call on line
+ L.
+ </p>
+ <p>The <c>XXL</c> operator is defined for the interpretation of
+ any of the LineOp operators applied to a set of function
+ calls. The result is that of replacing the function call with
+ a line numbered function call, that is, each of the two
+ functions of the call is replaced by a pair of the function and
+ the line where the function is defined. The effect of the
+ <c>XXL</c> operator can be undone by the LineOp operators. For
+ instance, <c>(Lin)&nbsp;(XXL)&nbsp;(Lin)&nbsp;E</c> is
+ equivalent to <c>(Lin)&nbsp;E</c>.
+ </p>
+ <p>The <c>+</c>, <c>-</c>, <c>*</c> and <c>#</c> operators are
+ defined for line number expressions, provided the operands are
+ compatible. The LineOp operators are also defined for
+ modules, applications, and releases; the operand is implicitly
+ converted to functions. Similarly, the cast operator is defined
+ for the interpretation of the LineOp operators.
+ </p>
+ <p>The interpretation of the <marker id="count"></marker>
+<em>counting operator</em> is the number of elements of a set. The operator
+ is undefined for closures. The <c>+</c>, <c>-</c> and <c>*</c>
+ operators are interpreted as the obvious arithmetical operators
+ when applied to numbers. The syntax of the counting operator:
+ </p>
+ <list type="bulleted">
+ <item>Expression ::= CountOp Expression</item>
+ <item>CountOp ::= <c>#</c></item>
+ </list>
+ <p>All binary operators are left associative; for instance,
+ <c>A&nbsp;|&nbsp;B &nbsp;||&nbsp;C</c> is equivalent to
+ <c>(A&nbsp;|&nbsp;B)&nbsp;||&nbsp;C</c>. The following is a list
+ of all operators, in increasing order of <marker id="precedence"></marker>
+<em>precedence</em>:
+ </p>
+ <list type="bulleted">
+ <item><c>+</c>, <c>-</c></item>
+ <item><c>*</c></item>
+ <item><c>#</c></item>
+ <item><c>|</c>, <c>||</c>, <c>|||</c></item>
+ <item><c>of</c></item>
+ <item><c>(</c>Type<c>)</c></item>
+ <item><c>closure</c>, <c>components</c>, <c>condensation</c>,
+ <c>domain</c>, <c>range</c>, <c>strict</c></item>
+ </list>
+ <p>Parentheses are used for grouping, either to make an expression
+ more readable or to override the default precedence of operators:
+ </p>
+ <list type="bulleted">
+ <item>Expression ::= <c>(</c> Expression <c>)</c></item>
+ </list>
+ <p>A <marker id="query"></marker>
+<em>query</em> is a non-empty sequence of
+ statements. A statement is either an assignment of a user
+ variable or an expression. The value of an assignment is the
+ value of the right hand side expression. It makes no sense to
+ put a plain expression anywhere else but last in queries. The
+ syntax of queries is summarized by these productions:
+ </p>
+ <list type="bulleted">
+ <item>Query ::= Statement<c>,</c>&nbsp;...</item>
+ <item>Statement ::= Assignment | Expression</item>
+ <item>Assignment ::= Variable <c>:=</c> Expression
+ | Variable <c>=</c> Expression</item>
+ </list>
+ <p>A variable cannot be assigned a new value unless first removed.
+ Variables assigned to by the <c>=</c> operator are removed at
+ the end of the query, while variables assigned to by the
+ <c>:=</c> operator can only be removed by calls to
+ <c>forget</c>. There are no user variables when module data
+ need to be set up again; if any of the functions that make it
+ necessary to set up module data again is called, all user
+ variables are forgotten.
+ </p>
+ <p><em>Types</em></p>
+ <pre>
+application() = atom()
+arity() = int() | -1
+bool() = true | false
+call() = {atom(), atom()} | funcall()
+constant() = mfa() | module() | application() | release()
+directory() = string()
+file() = string()
+funcall() = {mfa(), mfa()}
+function() = atom()
+int() = integer() >= 0
+library() = atom()
+library_path() = path() | code_path
+mfa() = {module(), function(), arity()}
+mode() = functions | modules
+module() = atom()
+release() = atom()
+string_position() = int() | at_end
+variable() = atom()
+xref() = atom() | pid() </pre>
+ </description>
+ <funcs>
+ <func>
+ <name>add_application(Xref, Directory [, Options]) -> {ok, application()} | Error</name>
+ <fsummary>Add the modules of an application.</fsummary>
+ <type>
+ <v>Directory = directory()</v>
+ <v>Error = {error, module(), Reason}</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {builtins, bool()} | {name, application()} | {verbose, bool()} | {warnings, bool()}</v>
+ <v>Reason = {application_clash, {application(), directory(), directory()}} | {file_error, file(), error()} | {invalid_filename, term()} | {invalid_options, term()} | -&nbsp;see&nbsp;also&nbsp;add_directory&nbsp;-</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Adds an application, the modules of the application and <seealso marker="#module_data">module data</seealso> of the
+ modules to an <seealso marker="#xref_server">Xref server</seealso>.
+ The modules will be members of the application.
+ The default is to use the base name of the
+ directory with the version removed as application name, but
+ this can be overridden by the <c>name</c> option. Returns the
+ name of the application.
+ </p>
+ <p>If the given directory has a subdirectory named
+ <c>ebin</c>, modules (BEAM files) are searched for in that
+ directory, otherwise modules are searched for in the given
+ directory.
+ </p>
+ <p>If the <seealso marker="#mode">mode</seealso> of the Xref
+ server is <c>functions</c>, BEAM files that contain no
+ <seealso marker="#debug_info">debug information</seealso> are
+ ignored.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>add_directory(Xref, Directory [, Options]) -> {ok, Modules} | Error</name>
+ <fsummary>Add the modules in a directory.</fsummary>
+ <type>
+ <v>Directory = directory()</v>
+ <v>Error = {error, module(), Reason}</v>
+ <v>Modules = [module()]</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {builtins, bool()} | {recurse, bool()} | {verbose, bool()} | {warnings, bool()}</v>
+ <v>Reason = {file_error, file(), error()} | {invalid_filename, term()} | {invalid_options, term()} | {unrecognized_file, file()} | -&nbsp;error from beam_lib:chunks/2&nbsp;-</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Adds the modules found in the given directory and the <seealso marker="#module_data">modules' data</seealso>
+ to an <seealso marker="#xref_server">Xref server</seealso>.
+ The default is not to examine subdirectories, but if the option
+ <c>recurse</c> has the value <c>true</c>, modules are searched
+ for in subdirectories on all levels as well as in the given
+ directory.
+ Returns a sorted list of the names of the added modules.
+ </p>
+ <p>The modules added will not be members of any applications.
+ </p>
+ <p>If the <seealso marker="#mode">mode</seealso> of the Xref
+ server is <c>functions</c>, BEAM files that contain no
+ <seealso marker="#debug_info">debug information</seealso> are
+ ignored.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>add_module(Xref, File [, Options]) -> {ok, module()} | Error</name>
+ <fsummary>Add a module.</fsummary>
+ <type>
+ <v>Error = {error, module(), Reason}</v>
+ <v>File = file()</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {builtins, bool()} | {verbose, bool()} | {warnings, bool()}</v>
+ <v>Reason = {file_error, file(), error()} | {invalid_filename, term()} | {invalid_options, term()} | {module_clash, {module(), file(), file()}} | {no_debug_info, file()} | -&nbsp;error from beam_lib:chunks/2&nbsp;-</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Adds a module and its <seealso marker="#module_data">module data</seealso> to an <seealso marker="#xref_server">Xref server</seealso>.
+ The module will not be member of any application.
+ Returns the name of the module.
+ </p>
+ <p>If the <seealso marker="#mode">mode</seealso> of the Xref
+ server is <c>functions</c>, and the BEAM file contains no
+ <seealso marker="#debug_info">debug information</seealso>,
+ the error message <c>no_debug_info</c> is returned.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>add_release(Xref, Directory [, Options]) -> {ok, release()} | Error</name>
+ <fsummary>Add the modules of a release.</fsummary>
+ <type>
+ <v>Directory = directory()</v>
+ <v>Error = {error, module(), Reason}</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {builtins, bool()} | {name, release()} | {verbose, bool()} | {warnings, bool()}</v>
+ <v>Reason = {application_clash, {application(), directory(), directory()}} | {file_error, file(), error()} | {invalid_filename, term()} | {invalid_options, term()} | {release_clash, {release(), directory(), directory()}} | -&nbsp;see&nbsp;also&nbsp;add_directory&nbsp;-</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Adds a release, the applications of the release, the
+ modules of the applications, and <seealso marker="#module_data">module data</seealso> of the
+ modules to an <seealso marker="#xref_server">Xref server</seealso>.
+ The applications will be members of the release,
+ and the modules will be members of the applications.
+ The default is to use the base name of the
+ directory as release name, but this can be overridden by the
+ <c>name</c> option. Returns the name of the release.
+ </p>
+ <p>If the given directory has a subdirectory named <c>lib</c>,
+ the directories in that directory are assumed to be
+ application directories, otherwise all subdirectories of the
+ given directory are assumed to be application directories.
+ If there are several versions of some application, the one
+ with the highest version is chosen.
+ </p>
+ <p>If the <seealso marker="#mode">mode</seealso> of the Xref
+ server is <c>functions</c>, BEAM files that contain no
+ <seealso marker="#debug_info">debug information</seealso> are
+ ignored.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>analyze(Xref, Analysis [, Options]) -> {ok, Answer} | Error</name>
+ <fsummary>Evaluate a predefined analysis.</fsummary>
+ <type>
+ <v>Analysis = undefined_function_calls | undefined_functions | locals_not_used | exports_not_used | deprecated_function_calls | {deprecated_function_calls, DeprFlag} | deprecated_functions | {deprecated_functions, DeprFlag} | {call, FuncSpec} | {use, FuncSpec} | {module_call, ModSpec} | {module_use, ModSpec} | {application_call, AppSpec} | {application_use, AppSpec} | {release_call, RelSpec} | {release_use, RelSpec}</v>
+ <v>Answer = [term()]</v>
+ <v>AppSpec = application() | [application()]</v>
+ <v>DeprFlag = next_version | next_major_release | eventually</v>
+ <v>Error = {error, module(), Reason}</v>
+ <v>FuncSpec = mfa() | [mfa()]</v>
+ <v>ModSpec = module() | [module()]</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {verbose, bool()}</v>
+ <v>RelSpec = release() | [release()]</v>
+ <v>Reason = {invalid_options, term()} | {parse_error, string_position(), term()} | {unavailable_analysis, term()} | {unknown_analysis, term()} | {unknown_constant, string()} | {unknown_variable, variable()}</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p> <marker id="analyze"></marker>
+Evaluates a predefined analysis.
+ Returns a sorted list without duplicates of <c>call()</c> or
+ <c>constant()</c>, depending on the chosen analysis. The
+ predefined analyses, which operate on all <seealso marker="#analyzed_module">analyzed modules</seealso>, are
+ (analyses marked with (*) are available in <c>functions</c><seealso marker="#mode">mode</seealso> only):</p>
+ <taglist>
+ <tag><c>undefined_function_calls</c>(*)</tag>
+ <item>Returns a list of calls to <seealso marker="#undefined_function">undefined functions</seealso>.</item>
+ <tag><c>undefined_functions</c></tag>
+ <item>Returns a list of <seealso marker="#undefined_function">undefined functions</seealso>. </item>
+ <tag><c>locals_not_used</c>(*)</tag>
+ <item>Returns a list of local functions that have not been
+ locally used.</item>
+ <tag><c>exports_not_used</c></tag>
+ <item>Returns a list of exported functions that have not been
+ externally used.</item>
+ <tag><c>deprecated_function_calls</c>(*)</tag>
+ <item>Returns a list of external calls to <seealso marker="#deprecated_function">deprecated functions</seealso>.</item>
+ <tag><c>{deprecated_function_calls, DeprFlag}</c>(*)</tag>
+ <item>Returns a list of external calls to deprecated
+ functions. If <c>DeprFlag</c> is equal to
+ <c>next_version</c>, calls to functions to be removed in
+ next version are returned. If <c>DeprFlag</c> is equal to
+ <c>next_major_release</c>, calls to functions to be
+ removed in next major release are returned as well as
+ calls to functions to be removed in next version. Finally,
+ if <c>DeprFlag</c> is equal to <c>eventually</c>, all
+ calls to functions to be removed are returned, including
+ calls to functions to be removed in next version or next
+ major release.</item>
+ <tag><c>deprecated_functions</c></tag>
+ <item>Returns a list of externally used deprecated
+ functions.</item>
+ <tag><c>{deprecated_functions, DeprFlag}</c></tag>
+ <item>Returns a list of externally used deprecated
+ functions. If <c>DeprFlag</c> is equal to
+ <c>next_version</c>, functions to be removed in next
+ version are returned. If <c>DeprFlag</c> is equal to
+ <c>next_major_release</c>, functions to be removed in next
+ major release are returned as well as functions to be
+ removed in next version. Finally, if <c>DeprFlag</c> is
+ equal to <c>eventually</c>, all functions to be removed
+ are returned, including functions to be removed in next
+ version or next major release.</item>
+ <tag><c>{call, FuncSpec}</c>(*)</tag>
+ <item>Returns a list of functions called by some of the given
+ functions.</item>
+ <tag><c>{use, FuncSpec}</c>(*)</tag>
+ <item>Returns a list of functions that use some of the given
+ functions.</item>
+ <tag><c>{module_call, ModSpec}</c></tag>
+ <item>Returns a list of modules called by some of the given
+ modules.</item>
+ <tag><c>{module_use, ModSpec}</c></tag>
+ <item>Returns a list of modules that use some of the given
+ modules.</item>
+ <tag><c>{application_call, AppSpec}</c></tag>
+ <item>Returns a list of applications called by some of the given
+ applications.</item>
+ <tag><c>{application_use, AppSpec}</c></tag>
+ <item>Returns a list of applications that use some of the given
+ applications.</item>
+ <tag><c>{release_call, RelSpec}</c></tag>
+ <item>Returns a list of releases called by some of the given
+ releases.</item>
+ <tag><c>{release_use, RelSpec}</c></tag>
+ <item>Returns a list of releases that use some of the given
+ releases.</item>
+ </taglist>
+ </desc>
+ </func>
+ <func>
+ <name>d(Directory) -> [DebugInfoResult] | [NoDebugInfoResult] | Error</name>
+ <fsummary>Check the modules in a directory using the code path.</fsummary>
+ <type>
+ <v>Directory = directory()</v>
+ <v>DebugInfoResult = {deprecated, [funcall()]} | {undefined, [funcall()]} | {unused, [mfa()]}</v>
+ <v>Error = {error, module(), Reason}</v>
+ <v>NoDebugInfoResult = {deprecated, [mfa()]} | {undefined, [mfa()]}</v>
+ <v>Reason = {file_error, file(), error()} | {invalid_filename, term()} | {unrecognized_file, file()} | -&nbsp;error from beam_lib:chunks/2&nbsp;-</v>
+ </type>
+ <desc>
+ <p>The modules found in the given directory are checked for
+ calls to <seealso marker="#deprecated_function">deprecated functions</seealso>, calls to <seealso marker="#undefined_function">undefined functions</seealso>,
+ and for unused local functions. The code path is used as
+ <seealso marker="#library_path">library path</seealso>.
+ </p>
+ <p>If some of the found BEAM files contain <seealso marker="#debug_info">debug information</seealso>, then those
+ modules are checked and a list of tuples is returned. The
+ first element of each tuple is one of:
+ </p>
+ <list type="bulleted">
+ <item><c>deprecated</c>, the second element is a sorted list
+ of calls to deprecated functions;</item>
+ <item><c>undefined</c>, the second element is a sorted list
+ of calls to undefined functions;</item>
+ <item><c>unused</c>, the second element is a sorted list of
+ unused local functions.</item>
+ </list>
+ <p>If no BEAM file contains debug information, then a list of
+ tuples is returned. The first element of each tuple is one
+ of:
+ </p>
+ <list type="bulleted">
+ <item><c>deprecated</c>, the second element is a sorted list
+ of externally used deprecated functions;</item>
+ <item><c>undefined</c>, the second element is a sorted list
+ of undefined functions.</item>
+ </list>
+ </desc>
+ </func>
+ <func>
+ <name>forget(Xref) -> ok</name>
+ <name>forget(Xref, Variables) -> ok | Error</name>
+ <fsummary>Remove user variables and their values.</fsummary>
+ <type>
+ <v>Error = {error, module(), Reason}</v>
+ <v>Reason = {not_user_variable, term()}</v>
+ <v>Variables = [variable()] | variable()</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p><c>forget/1</c> and <c>forget/2</c> remove all or some of
+ the <seealso marker="#user_variable">user variables</seealso> of an <seealso marker="#xref_server">xref server</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>format_error(Error) -> Chars</name>
+ <fsummary>Return an English description of an Xref error reply.</fsummary>
+ <type>
+ <v>Error = {error, module(), term()}</v>
+ <v>Chars = [char() | Chars]</v>
+ </type>
+ <desc>
+ <p>Given the error returned by any function of this module,
+ the function <c>format_error</c> returns a descriptive string
+ of the error in English. For file errors, the function
+ <c>format_error/1</c> in the <c>file</c> module is called.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_default(Xref) -> [{Option, Value}]</name>
+ <name>get_default(Xref, Option) -> {ok, Value} | Error</name>
+ <fsummary>Return the default values of options.</fsummary>
+ <type>
+ <v>Error = {error, module(), Reason}</v>
+ <v>Option = builtins | recurse | verbose | warnings</v>
+ <v>Reason = {invalid_options, term()}</v>
+ <v>Value = bool()</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Returns the default values of one or more options.</p>
+ </desc>
+ </func>
+ <func>
+ <name>get_library_path(Xref) -> {ok, LibraryPath}</name>
+ <fsummary>Return the library path.</fsummary>
+ <type>
+ <v>LibraryPath = library_path()</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Returns the <seealso marker="#library_path">library path</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>info(Xref) -> [Info]</name>
+ <name>info(Xref, Category) -> [{Item, [Info]}]</name>
+ <name>info(Xref, Category, Items) -> [{Item, [Info]}]</name>
+ <fsummary>Return information about an Xref server.</fsummary>
+ <type>
+ <v>Application = [] | [application()]</v>
+ <v>Category = modules | applications | releases | libraries</v>
+ <v>Info = {application, Application} | {builtins, bool()} | {directory, directory()} | {library_path, library_path()} | {mode, mode()} | {no_analyzed_modules, int()} | {no_applications, int()} | {no_calls, {NoResolved, NoUnresolved}} | {no_function_calls, {NoLocal, NoResolvedExternal, NoUnresolved}} | {no_functions, {NoLocal, NoExternal}} | {no_inter_function_calls, int()} | {no_releases, int()} | {release, Release} | {version, Version}</v>
+ <v>Item = module() | application() | release() | library()</v>
+ <v>Items = Item | [Item]</v>
+ <v>NoLocal = NoExternal = NoResolvedExternal, NoResolved = NoUnresolved = int()</v>
+ <v>Release = [] | [release()]</v>
+ <v>Version = [int()]</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>The <c>info</c> functions return information as a list of
+ pairs {Tag,&nbsp;term()} in some order about the state and the
+ <seealso marker="#module_data">module data</seealso> of an <seealso marker="#xref_server">Xref server</seealso>.
+ </p>
+ <p><c>info/1</c> returns information with the following tags
+ (tags marked with (*) are available in <c>functions</c>
+ mode only):</p>
+ <list type="bulleted">
+ <item><c>library_path</c>, the <seealso marker="#library_path">library path</seealso>;</item>
+ <item><c>mode</c>, the <seealso marker="#mode">mode</seealso>;</item>
+ <item><c>no_releases</c>, number of releases;</item>
+ <item><c>no_applications</c>, total number of applications
+ (of all releases);</item>
+ <item><c>no_analyzed_modules</c>, total number of <seealso marker="#analyzed_module">analyzed modules</seealso>;</item>
+ <item><c>no_calls</c> (*), total number of calls (in all
+ modules), regarding instances of one function call in
+ different lines as separate calls;</item>
+ <item><c>no_function_calls</c> (*), total number of <seealso marker="#local_call">local calls</seealso>, resolved <seealso marker="#external_call">external calls</seealso> and
+ <seealso marker="#unresolved_call">unresolved calls</seealso>;</item>
+ <item><c>no_functions</c> (*), total number of local and exported
+ functions;</item>
+ <item><c>no_inter_function_calls</c> (*), total number of
+ calls of the <seealso marker="#inter_call_graph">Inter Call Graph</seealso>.</item>
+ </list>
+ <p><c>info/2</c> and <c>info/3</c> return information about
+ all or some of the analyzed modules, applications, releases
+ or library modules of an Xref server.
+ The following information is returned for every analyzed module:</p>
+ <list type="bulleted">
+ <item><c>application</c>, an empty list if the module does
+ not belong to any application, otherwise a list of
+ the application name;</item>
+ <item><c>builtins</c>, whether calls to BIFs are included
+ in the module's data;</item>
+ <item><c>directory</c>, the directory where the
+ module's BEAM file is located;</item>
+ <item><c>no_calls</c> (*), number of calls, regarding
+ instances of one function call in different lines as
+ separate calls;</item>
+ <item><c>no_function_calls</c> (*), number of local
+ calls, resolved external calls and unresolved calls;</item>
+ <item><c>no_functions</c> (*), number of local and exported
+ functions;</item>
+ <item><c>no_inter_function_calls</c> (*), number of calls
+ of the Inter Call Graph;</item>
+ </list>
+ <p>The following information is returned for every application:</p>
+ <list type="bulleted">
+ <item><c>directory</c>, the directory where the
+ modules' BEAM files are located;</item>
+ <item><c>no_analyzed_modules</c>, number of analyzed
+ modules;</item>
+ <item><c>no_calls</c> (*), number of calls of the
+ application's modules, regarding instances of
+ one function call in different lines as separate calls;</item>
+ <item><c>no_function_calls</c> (*), number of local
+ calls, resolved external calls and unresolved calls of the
+ application's modules;</item>
+ <item><c>no_functions</c> (*), number of local and exported
+ functions of the application's modules;</item>
+ <item><c>no_inter_function_calls</c> (*), number of calls
+ of the Inter Call Graph of the
+ application's modules;</item>
+ <item><c>release</c>, an empty list if the application does not
+ belong to any release, otherwise a list of the release name;</item>
+ <item><c>version</c>, the application's version as
+ a list of numbers. For instance, the directory "kernel-2.6"
+ results in the application name <c>kernel</c> and the
+ application version [2,6]; "kernel" yields the name
+ <c>kernel</c> and the version [].</item>
+ </list>
+ <p>The following information is returned for every release:</p>
+ <list type="bulleted">
+ <item><c>directory</c>, the release directory;</item>
+ <item><c>no_analyzed_modules</c>, number of analyzed
+ modules;</item>
+ <item><c>no_applications</c>, number of applications;</item>
+ <item><c>no_calls</c> (*), number of calls of the
+ release's modules, regarding
+ instances of one function call in different lines as
+ separate calls;</item>
+ <item><c>no_function_calls</c> (*), number of local
+ calls, resolved external calls and unresolved
+ calls of the release's modules;</item>
+ <item><c>no_functions</c> (*), number of local and exported
+ functions of the release's modules;</item>
+ <item><c>no_inter_function_calls</c> (*), number of calls
+ of the Inter Call Graph of the release's modules.</item>
+ </list>
+ <p>The following information is returned for every library module:</p>
+ <list type="bulleted">
+ <item><c>directory</c>, the directory where the <seealso marker="#library_module">library module's</seealso> BEAM file is located.</item>
+ </list>
+ <p>For every number of calls, functions etc. returned by the
+ <c>no_</c> tags, there is a query returning the same number.
+ Listed below are examples of such queries. Some of the
+ queries return the sum of a two or more of the <c>no_</c>
+ tags numbers. <c>mod</c> (<c>app</c>, <c>rel</c>) refers to
+ any module (application, release).
+ </p>
+ <list type="bulleted">
+ <item>
+ <p><c>no_analyzed_modules</c></p>
+ <list type="bulleted">
+ <item><c>"# AM"</c> (info/1)</item>
+ <item><c>"# (Mod) app:App"</c>
+ (application)</item>
+ <item><c>"# (Mod) rel:Rel"</c> (release)</item>
+ </list>
+ </item>
+ <item>
+ <p><c>no_applications</c></p>
+ <list type="bulleted">
+ <item><c>"# A"</c> (info/1)</item>
+ </list>
+ </item>
+ <item>
+ <p><c>no_calls</c>. The sum of the number of resolved and
+ unresolved calls:</p>
+ <list type="bulleted">
+ <item><c>"# (XLin) E + # (LLin) E"</c> (info/1)</item>
+ <item><c>"T = E | mod:Mod, # (LLin) T + # (XLin) T"</c>
+ (module)</item>
+ <item><c>"T = E | app:App, # (LLin) T + # (XLin) T"</c>
+ (application)</item>
+ <item><c>"T = E | rel:Rel, # (LLin) T + # (XLin) T"</c>
+ (release)</item>
+ </list>
+ </item>
+ <item>
+ <p><c>no_functions</c>. Functions in library modules and
+ the functions <c>module_info/0,1</c> are not counted by
+ <c>info</c>. Assuming that <c>"Extra := _:module_info/\\"(0|1)\\" + LM"</c> has been evaluated, the
+ sum of the number of local and exported functions are:</p>
+ <list type="bulleted">
+ <item><c>"# (F - Extra)"</c> (info/1)</item>
+ <item><c>"# (F * mod:Mod - Extra)"</c> (module)</item>
+ <item><c>"# (F * app:App - Extra)"</c> (application)</item>
+ <item><c>"# (F * rel:Rel - Extra)"</c> (release)</item>
+ </list>
+ </item>
+ <item>
+ <p><c>no_function_calls</c>. The sum of the number of
+ local calls, resolved external calls and unresolved calls:</p>
+ <list type="bulleted">
+ <item><c>"# LC + # XC"</c> (info/1)</item>
+ <item><c>"# LC | mod:Mod + # XC | mod:Mod"</c> (module)</item>
+ <item><c>"# LC | app:App + # XC | app:App"</c> (application)</item>
+ <item><c>"# LC | rel:Rel + # XC | mod:Rel"</c> (release)</item>
+ </list>
+ </item>
+ <item>
+ <p><c>no_inter_function_calls</c></p>
+ <list type="bulleted">
+ <item><c>"# EE"</c> (info/1)</item>
+ <item><c>"# EE | mod:Mod"</c> (module)</item>
+ <item><c>"# EE | app:App"</c> (application)</item>
+ <item><c>"# EE | rel:Rel"</c> (release)</item>
+ </list>
+ </item>
+ <item>
+ <p><c>no_releases</c></p>
+ <list type="bulleted">
+ <item><c>"# R"</c> (info/1)</item>
+ </list>
+ </item>
+ </list>
+ </desc>
+ </func>
+ <func>
+ <name>m(Module) -> [DebugInfoResult] | [NoDebugInfoResult] | Error</name>
+ <name>m(File) -> [DebugInfoResult] | [NoDebugInfoResult] | Error</name>
+ <fsummary>Check a module using the code path.</fsummary>
+ <type>
+ <v>DebugInfoResult = {deprecated, [funcall()]} | {undefined, [funcall()]} | {unused, [mfa()]}</v>
+ <v>Error = {error, module(), Reason}</v>
+ <v>File = file()</v>
+ <v>Module = module()</v>
+ <v>NoDebugInfoResult = {deprecated, [mfa()]} | {undefined, [mfa()]}</v>
+ <v>Reason = {file_error, file(), error()} | {interpreted, module()} | {invalid_filename, term()} | {cover_compiled, module()} | {no_such_module, module()} | -&nbsp;error from beam_lib:chunks/2&nbsp;-</v>
+ </type>
+ <desc>
+ <p>The given BEAM file (with or without the <c>.beam</c>
+ extension) or the file found by calling
+ <c>code:which(Module)</c> is checked for calls to <seealso marker="#deprecated_function">deprecated functions</seealso>, calls to <seealso marker="#undefined_function">undefined functions</seealso>,
+ and for unused local functions. The code path is used as
+ <seealso marker="#library_path">library path</seealso>.
+ </p>
+ <p>If the BEAM file contains <seealso marker="#debug_info">debug information</seealso>, then a
+ list of tuples is returned. The first element of each tuple
+ is one of:
+ </p>
+ <list type="bulleted">
+ <item><c>deprecated</c>, the second element is a sorted list
+ of calls to deprecated functions;</item>
+ <item><c>undefined</c>, the second element is a sorted list
+ of calls to undefined functions;</item>
+ <item><c>unused</c>, the second element is a sorted list of
+ unused local functions.</item>
+ </list>
+ <p>If the BEAM file does not contain debug information, then a
+ list of tuples is returned. The first element of each tuple
+ is one of:
+ </p>
+ <list type="bulleted">
+ <item><c>deprecated</c>, the second element is a sorted list
+ of externally used deprecated functions;</item>
+ <item><c>undefined</c>, the second element is a sorted list
+ of undefined functions.</item>
+ </list>
+ </desc>
+ </func>
+ <func>
+ <name>q(Xref, Query [, Options]) -> {ok, Answer} | Error</name>
+ <fsummary>Evaluate a query.</fsummary>
+ <type>
+ <v>Answer = false | [constant()] | [Call] | [Component] | int() | [DefineAt] | [CallAt] | [AllLines]</v>
+ <v>Call = call() | ComponentCall</v>
+ <v>ComponentCall = {Component, Component}</v>
+ <v>Component = [constant()]</v>
+ <v>DefineAt = {mfa(), LineNumber}</v>
+ <v>CallAt = {funcall(), LineNumbers}</v>
+ <v>AllLines = {{DefineAt, DefineAt}, LineNumbers}</v>
+ <v>Error = {error, module(), Reason}</v>
+ <v>LineNumbers = [LineNumber]</v>
+ <v>LineNumber = int()</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {verbose, bool()}</v>
+ <v>Query = string() | atom()</v>
+ <v>Reason = {invalid_options, term()} | {parse_error, string_position(), term()} | {type_error, string()} | {type_mismatch, string(), string()} | {unknown_analysis, term()} | {unknown_constant, string()} | {unknown_variable, variable()} | {variable_reassigned, string()}</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Evaluates a <seealso marker="#query">query</seealso> in the
+ context of an <seealso marker="#xref_server">Xref server</seealso>, and returns the value of the last
+ statement. The syntax of the value depends on the
+ expression:
+ </p>
+ <list type="bulleted">
+ <item>A set of calls is represented by a sorted list without
+ duplicates of <c>call()</c>.</item>
+ <item>A set of constants is represented by a sorted list
+ without duplicates of <c>constant()</c>.</item>
+ <item>A set of strongly connected components is a sorted list
+ without duplicates of <c>Component</c>.</item>
+ <item>A set of calls between strongly connected components is
+ a sorted list without duplicates of <c>ComponentCall</c>.</item>
+ <item>A chain of calls is represented by a list of
+ <c>constant()</c>. The list contains the From vertex of every
+ call and the To vertex of the last call.</item>
+ <item>The <c>of</c> operator returns <c>false</c> if no chain
+ of calls between the given constants can be found.</item>
+ <item>The value of the <c>closure</c> operator (the
+ <c>digraph</c> representation) is represented by the atom
+ <c>'closure()'</c>.</item>
+ <item>A set of line numbered functions is represented by a sorted
+ list without duplicates of <c>DefineAt</c>.</item>
+ <item>A set of line numbered function calls is represented by
+ a sorted list without duplicates of <c>CallAt</c>.</item>
+ <item>A set of line numbered functions and function calls is
+ represented by a sorted list without duplicates of
+ <c>AllLines</c>.</item>
+ </list>
+ <p>For both <c>CallAt</c> and <c>AllLines</c> it holds that for
+ no list element is <c>LineNumbers</c> an empty list; such
+ elements have been removed. The constants of <c>component</c>
+ and the integers of <c>LineNumbers</c> are sorted and without
+ duplicates.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>remove_application(Xref, Applications) -> ok | Error</name>
+ <fsummary>Remove applications and their modules.</fsummary>
+ <type>
+ <v>Applications = application() | [application()]</v>
+ <v>Error = {error, module(), Reason}</v>
+ <v>Reason = {no_such_application, application()}</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Removes applications and their modules and <seealso marker="#module_data">module data</seealso> from an <seealso marker="#xref_server">Xref server</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>remove_module(Xref, Modules) -> ok | Error</name>
+ <fsummary>Remove analyzed modules.</fsummary>
+ <type>
+ <v>Error = {error, module(), Reason}</v>
+ <v>Modules = module() | [module()]</v>
+ <v>Reason = {no_such_module, module()}</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Removes <seealso marker="#analyzed_module">analyzed modules</seealso> and <seealso marker="#module_data">module data</seealso> from an <seealso marker="#xref_server">Xref server</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>remove_release(Xref, Releases) -> ok | Error</name>
+ <fsummary>Remove releases and their applications and modules.</fsummary>
+ <type>
+ <v>Error = {error, module(), Reason}</v>
+ <v>Reason = {no_such_release, release()}</v>
+ <v>Releases = release() | [release()]</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Removes releases and their applications, modules and
+ <seealso marker="#module_data">module data</seealso> from an
+ <seealso marker="#xref_server">Xref server</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>replace_application(Xref, Application, Directory [, Options]) -> {ok, application()} | Error</name>
+ <fsummary>Replace an application's modules.</fsummary>
+ <type>
+ <v>Application = application()</v>
+ <v>Directory = directory()</v>
+ <v>Error = {error, module(), Reason}</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {builtins, bool()} | {verbose, bool()} | {warnings, bool()}</v>
+ <v>Reason = {no_such_application, application()} | -&nbsp;see&nbsp;also&nbsp;add_application&nbsp;-</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Replaces the modules of an application with other modules
+ read from an application directory. Release membership of the
+ application is retained. Note that the name of the
+ application is kept; the name of the given directory is not
+ used.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>replace_module(Xref, Module, File [, Options]) -> {ok, module()} | Error</name>
+ <fsummary>Replace an analyzed module.</fsummary>
+ <type>
+ <v>Error = {error, module(), Reason}</v>
+ <v>File = file()</v>
+ <v>Module = module()</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {verbose, bool()} | {warnings, bool()}</v>
+ <v>ReadModule = module()</v>
+ <v>Reason = {module_mismatch, module(), ReadModule} | {no_such_module, module()} | -&nbsp;see&nbsp;also&nbsp;add_module&nbsp;-</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Replaces <seealso marker="#module_data">module data</seealso> of an <seealso marker="#analyzed_module">analyzed module</seealso> with
+ data read from a BEAM file. Application membership of the
+ module is retained, and so is the value of the
+ <c>builtins</c> option of the module. An error is returned
+ if the name of the read module differs from the given
+ module.
+ </p>
+ <p>The <c>update</c> function is an alternative for updating
+ module data of recompiled modules.</p>
+ </desc>
+ </func>
+ <func>
+ <name>set_default(Xref, Option, Value) -> {ok, OldValue} | Error</name>
+ <name>set_default(Xref, OptionValues) -> ok | Error</name>
+ <fsummary>Set the default values of options.</fsummary>
+ <type>
+ <v>Error = {error, module(), Reason}</v>
+ <v>OptionValues = [OptionValue] | OptionValue</v>
+ <v>OptionValue = {Option, Value}</v>
+ <v>Option = builtins | recurse | verbose | warnings</v>
+ <v>Reason = {invalid_options, term()}</v>
+ <v>Value = bool()</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Sets the default value of one or more options.
+ The options that can be set this way are:</p>
+ <list type="bulleted">
+ <item><c>builtins</c>, with initial default value <c>false</c>;</item>
+ <item><c>recurse</c>, with initial default value <c>false</c>;</item>
+ <item><c>verbose</c>, with initial default value <c>false</c>;</item>
+ <item><c>warnings</c>, with initial default value <c>true</c>.</item>
+ </list>
+ <p>The initial default values are set when creating an <seealso marker="#xref_server">Xref server</seealso>.
+ </p>
+ </desc>
+ </func>
+ <func>
+ <name>set_library_path(Xref, LibraryPath [, Options]) -> ok | Error</name>
+ <fsummary>Set the library path and finds the library modules.</fsummary>
+ <type>
+ <v>Error = {error, module(), Reason}</v>
+ <v>LibraryPath = library_path()</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {verbose, bool()}</v>
+ <v>Reason = {invalid_options, term()} | {invalid_path, term()}</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Sets the <seealso marker="#library_path">library path</seealso>. If the given path is a list of
+ directories, the set of <seealso marker="#library_module">library modules</seealso> is
+ determined by choosing the first module
+ encountered while traversing the directories in
+ the given order, for those modules that occur in more than
+ one directory. By default, the library path is an empty list.
+ </p>
+ <p>The library path <marker id="code_path"></marker>
+<c>code_path</c> is
+ used by the functions
+ <c>m/1</c> and <c>d/1</c>, but can also be set explicitly.
+ Note however that the code path will be traversed once for
+ each used <seealso marker="#library_module">library module</seealso> while setting up module data.
+ On the other hand, if there are only a few modules that are
+ used by not analyzed, using <c>code_path</c> may be faster
+ than setting the library path to <c>code:get_path()</c>.
+ </p>
+ <p>If the library path is set to <c>code_path</c>, the set of
+ library modules is not determined, and the <c>info</c>
+ functions will return empty lists of library modules.</p>
+ </desc>
+ </func>
+ <func>
+ <name>start(NameOrOptions) -> Return</name>
+ <fsummary>Create an Xref server.</fsummary>
+ <type>
+ <v>Name = atom()()</v>
+ <v>XrefOrOptions = Xref | Options</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {xref_mode, mode()} | term()</v>
+ <v>Return = {ok, pid()} | {error, {already_started, pid()}}</v>
+ </type>
+ <desc>
+ <p>Creates an <seealso marker="#xref_server">Xref server</seealso>.
+ The process may optionally be given a name.
+ The default <seealso marker="#mode">mode</seealso> is <c>functions</c>.
+ Options that are not recognized by Xref
+ are passed on to <c>gen_server:start/4</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>start(Name, Options) -> Return</name>
+ <fsummary>Create an Xref server.</fsummary>
+ <type>
+ <v>Name = atom()()</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {xref_mode, mode()} | term()</v>
+ <v>Return = {ok, pid()} | {error, {already_started, pid()}}</v>
+ </type>
+ <desc>
+ <p>Creates an <seealso marker="#xref_server">Xref server</seealso>
+ with a given name.
+ The default <seealso marker="#mode">mode</seealso> is <c>functions</c>.
+ Options that are not recognized by Xref
+ are passed on to <c>gen_server:start/4</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>stop(Xref)</name>
+ <fsummary>Delete an Xref server.</fsummary>
+ <type>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Stops an <seealso marker="#xref_server">Xref server</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>update(Xref [, Options]) -> {ok, Modules} | Error</name>
+ <fsummary>Replace newly compiled analyzed modules.</fsummary>
+ <type>
+ <v>Error = {error, module(), Reason}</v>
+ <v>Modules = [module()]</v>
+ <v>Options = [Option] | Option</v>
+ <v>Option = {verbose, bool()} | {warnings, bool()}</v>
+ <v>Reason = {invalid_options, term()} | {module_mismatch, module(), ReadModule} | -&nbsp;see&nbsp;also&nbsp;add_module&nbsp;-</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Replaces the <seealso marker="#module_data">module data</seealso> of all <seealso marker="#analyzed_module">analyzed modules</seealso> the BEAM
+ files of which have been modified since last read by an
+ <c>add</c> function or <c>update</c>. Application membership
+ of the modules is retained, and so is the value of the
+ <c>builtins</c> option. Returns a sorted list
+ of the names of the replaced modules.</p>
+ </desc>
+ </func>
+ <func>
+ <name>variables(Xref [, Options]) -> {ok, [VariableInfo]}</name>
+ <fsummary>Return the names of variables.</fsummary>
+ <type>
+ <v>Options = [Option] | Option</v>
+ <v>Option = predefined | user | {verbose, bool()}</v>
+ <v>Reason = {invalid_options, term()}</v>
+ <v>VariableInfo = {predefined, [variable()]} | {user, [variable()]}</v>
+ <v>Xref = xref()</v>
+ </type>
+ <desc>
+ <p>Returns a sorted lists of the names of the variables of an
+ <seealso marker="#xref_server">Xref server</seealso>.
+ The default is to return the <seealso marker="#user_variable">user variables</seealso> only.</p>
+ </desc>
+ </func>
+ </funcs>
+
+ <section>
+ <title>See Also</title>
+ <p>beam_lib(3), digraph(3), digraph_utils(3), regexp(3),
+ <seealso marker="xref_chapter">TOOLS User's Guide</seealso></p>
+ </section>
+</erlref>
+
diff --git a/lib/tools/doc/src/xref_chapter.xml b/lib/tools/doc/src/xref_chapter.xml
new file mode 100644
index 0000000000..39c5545af9
--- /dev/null
+++ b/lib/tools/doc/src/xref_chapter.xml
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2000</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Xref - The Cross Reference Tool</title>
+ <prepared>Hans Bolinder</prepared>
+ <responsible>nobody</responsible>
+ <docno></docno>
+ <approved>nobody</approved>
+ <checked>no</checked>
+ <date>2000-08-18</date>
+ <rev>PA1</rev>
+ <file>xref_chapter.xml</file>
+ </header>
+ <p>Xref is a cross reference tool that can be used for
+ finding dependencies between functions, modules, applications
+ and releases. It does so by analyzing the defined functions
+ and the function calls.
+ </p>
+ <p>In order to make Xref easy to use, there are predefined
+ analyses that perform some common tasks. Typically, a module
+ or a release can be checked for calls to undefined functions.
+ For the somewhat more advanced user there is a small, but
+ rather flexible, language that can be used for selecting parts
+ of the analyzed system and for doing some simple graph
+ analyses on selected calls.
+ </p>
+ <p>The following sections show some features of Xref, beginning
+ with a module check and a predefined analysis. Then follow
+ examples that can be skipped on the first reading; not all of
+ the concepts used are explained, and it is assumed that the
+ <seealso marker="xref">reference manual</seealso> has been at
+ least skimmed.
+ </p>
+
+ <section>
+ <title>Module Check</title>
+ <p>Assume we want to check the following module:
+ </p>
+ <pre>
+ -module(my_module).
+
+ -export([t/1]).
+
+ t(A) ->
+ my_module:t2(A).
+
+ t2(_) ->
+ true. </pre>
+ <p>Cross reference data are read from BEAM files, so the first
+ step when checking an edited module is to compile it:
+ </p>
+ <pre>
+ 1> <input>c(my_module, debug_info).</input>
+ ./my_module.erl:10: Warning: function t2/1 is unused
+ {ok, my_module} </pre>
+ <p>The <c>debug_info</c> option ensures that the BEAM file
+ contains debug information, which makes it possible to find
+ unused local functions.
+ </p>
+ <p>The module can now be checked for calls to <seealso marker="xref#deprecated_function">deprecated functions</seealso>, calls to <seealso marker="xref#undefined_function">undefined functions</seealso>,
+ and for unused local functions:
+ </p>
+ <pre>
+ 2> <input>xref:m(my_module)</input>
+ [{deprecated,[]},
+ {undefined,[{{my_module,t,1},{my_module,t2,1}}]},
+ {unused,[{my_module,t2,1}]}] </pre>
+ <p><c>m/1</c> is also suitable for checking that the
+ BEAM file of a module that is about to be loaded into a
+ running a system does not call any undefined functions. In
+ either case, the code path of the code server (see the module
+ <c>code</c>) is used for finding modules that export externally
+ called functions not exported by the checked module itself, so
+ called <seealso marker="xref#library_module">library modules</seealso>.
+ </p>
+ </section>
+
+ <section>
+ <title>Predefined Analysis</title>
+ <p>In the last example the module to analyze was given as an
+ argument to <c>m/1</c>, and the code path was (implicitly)
+ used as <seealso marker="xref#library_path">library path</seealso>. In this example an <seealso marker="xref#xref_server">xref server</seealso> will be used,
+ which makes it possible to analyze applications and releases,
+ and also to select the library path explicitly.
+ </p>
+ <p>Each Xref server is referred to by a unique name. The name
+ is given when creating the server:
+ </p>
+ <pre>
+ 1> <input>xref:start(s).</input>
+ {ok,&lt;0.27.0>} </pre>
+ <p>Next the system to be analyzed is added to the Xref server.
+ Here the system will be OTP, so no library path will be needed.
+ Otherwise, when analyzing a system that uses OTP, the OTP
+ modules are typically made library modules by
+ setting the library path to the default OTP code path (or to
+ <c>code_path</c>, see the <seealso marker="xref#code_path">reference manual</seealso>). By
+ default, the names of read BEAM files and warnings are output
+ when adding analyzed modules, but these messages can be avoided
+ by setting default values of some options:
+ </p>
+ <pre>
+ 2> <input>xref:set_default(s, [{verbose,false}, {warnings,false}]).</input>
+ ok
+ 3> <input>xref:add_release(s, code:lib_dir(), {name, otp}).</input>
+ {ok,otp} </pre>
+ <p><c>add_release/3</c> assumes that all subdirectories of the
+ library directory returned by <c>code:lib_dir()</c> contain
+ applications; the effect is that of reading all
+ applications' BEAM files.
+ </p>
+ <p>It is now easy to check the release for calls to undefined
+ functions:
+ </p>
+ <pre>
+ 4> <input>xref:analyze(s, undefined_function_calls).</input>
+ {ok, [...]} </pre>
+ <p>We can now continue with further analyses, or we can delete
+ the Xref server:
+ </p>
+ <pre>
+ 5> <input>xref:stop(s).</input> </pre>
+ <p>The check for calls to undefined functions is an example of a
+ predefined analysis, probably the most useful one. Other
+ examples are the analyses that find unused local
+ functions, or functions that call some given functions. See
+ the <seealso marker="xref#analyze">analyze/2,3</seealso>
+ functions for a complete list of predefined analyses.
+ </p>
+ <p>Each predefined analysis is a shorthand for a <seealso marker="xref#query">query</seealso>, a sentence of a tiny
+ language providing cross reference data as
+ values of <seealso marker="xref#predefined_variable">predefined variables</seealso>.
+ The check for calls to undefined functions can thus be stated as
+ a query:
+ </p>
+ <pre>
+ 4> <input>xref:q(s, "(XC - UC) || (XU - X - B)").</input>
+ {ok,[...]} </pre>
+ <p>The query asks for the restriction of external calls except the
+ unresolved calls to calls to functions that are externally used
+ but neither exported nor built-in functions (the <c>||</c>
+ operator restricts the used functions while the <c>|</c>
+ operator restricts the calling functions). The <c>-</c> operator
+ returns the difference of two sets, and the <c>+</c> operator to
+ be used below returns the union of two sets.
+ </p>
+ <p>The relationships between the predefined variables
+ <c>XU</c>, <c>X</c>, <c>B</c> and a few
+ others are worth elaborating upon.
+ The reference manual mentions two ways of expressing the set of
+ all functions, one that focuses on how they are defined:
+ <c>X&nbsp;+&nbsp;L&nbsp;+&nbsp;B&nbsp;+&nbsp;U</c>, and one
+ that focuses on how they are used:
+ <c>UU&nbsp;+&nbsp;LU&nbsp;+&nbsp;XU</c>.
+ The reference also mentions some <seealso marker="xref#simple_facts">facts</seealso> about the
+ variables:
+ </p>
+ <list type="bulleted">
+ <item><c>F</c> is equal to <c>L + X</c> (the defined functions
+ are the local functions and the external functions);</item>
+ <item><c>U</c> is a subset of <c>XU</c> (the unknown functions
+ are a subset of the externally used functions since
+ the compiler ensures that locally used functions are defined);</item>
+ <item><c>B</c> is a subset of <c>XU</c> (calls to built-in
+ functions are always external by definition, and unused
+ built-in functions are ignored);</item>
+ <item><c>LU</c> is a subset of <c>F</c> (the locally used
+ functions are either local functions or exported functions,
+ again ensured by the compiler);</item>
+ <item><c>UU</c> is equal to
+ <c>F&nbsp;-&nbsp;(XU&nbsp;+&nbsp;LU)</c> (the unused functions
+ are defined functions that are neither used externally nor
+ locally);</item>
+ <item><c>UU</c> is a subset of <c>F</c> (the unused functions
+ are defined in analyzed modules).</item>
+ </list>
+ <p>Using these facts, the two small circles in the picture below
+ can be combined.
+ </p>
+ <image file="venn1.gif">
+ <icaption>Definition and use of functions</icaption>
+ </image>
+ <p>It is often clarifying to mark the variables of a query in such
+ a circle. This is illustrated in the picture below for some of
+ the predefined analyses. Note that local functions used by local
+ functions only are not marked in the <c>locals_not_used</c>
+ circle. <marker id="venn2"></marker>
+</p>
+ <image file="venn2.gif">
+ <icaption>Some predefined analyses as subsets of all functions</icaption>
+ </image>
+ </section>
+
+ <section>
+ <title>Expressions</title>
+ <p>The module check and the predefined analyses are useful, but
+ limited. Sometimes more flexibility is needed, for instance one
+ might not need to apply a graph analysis on all calls, but some
+ subset will do equally well. That flexibility is provided with
+ a simple language. Below are some expressions of the language
+ with comments, focusing on elements of the language rather than
+ providing useful examples. The analyzed system is assumed to be
+ OTP, so in order to run the queries, first evaluate these calls:
+ </p>
+ <pre>
+ xref:start(s).
+ xref:add_release(s, code:root_dir()). </pre>
+ <taglist>
+ <tag><c>xref:q(s, "(Fun) xref : Mod").</c></tag>
+ <item>All functions of the <c>xref</c> module. </item>
+ <tag><c>xref:q(s, "xref : Mod * X").</c></tag>
+ <item>All exported functions of the <c>xref</c> module. The first
+ operand of the intersection operator <c>*</c> is implicitly
+ converted to the more special type of the second operand.</item>
+ <tag><c>xref:q(s, "(Mod) tools").</c></tag>
+ <item>All modules of the <c>tools</c> application.</item>
+ <tag><c>xref:q(s, '"xref_.*" : Mod').</c></tag>
+ <item>All modules with a name beginning with <c>xref_</c>.</item>
+ <tag><c>xref:q(s, "# E&nbsp;|&nbsp;X&nbsp;").</c></tag>
+ <item>Number of calls from exported functions.</item>
+ <tag><c>xref:q(s, "XC&nbsp;||&nbsp;L&nbsp;").</c></tag>
+ <item>All external calls to local functions.</item>
+ <tag><c>xref:q(s, "XC&nbsp;*&nbsp;LC").</c></tag>
+ <item>All calls that have both an external and a local version.</item>
+ <tag><c>xref:q(s, "(LLin) (LC * XC)").</c></tag>
+ <item>The lines where the local calls of the last example
+ are made.</item>
+ <tag><c>xref:q(s, "(XLin) (LC * XC)").</c></tag>
+ <item>The lines where the external calls of the example before
+ last are made.</item>
+ <tag><c>xref:q(s, "XC * (ME - strict ME)").</c></tag>
+ <item>External calls within some module.</item>
+ <tag><c>xref:q(s, "E&nbsp;|||&nbsp;kernel").</c></tag>
+ <item>All calls within the <c>kernel</c> application. </item>
+ <tag><c>xref:q(s, "closure&nbsp;E&nbsp;|&nbsp;kernel&nbsp;||&nbsp;kernel").</c></tag>
+ <item>All direct and indirect calls within the <c>kernel</c>
+ application. Both the calling and the used functions of
+ indirect calls are defined in modules of the kernel
+ application, but it is possible that some functions outside
+ the kernel application are used by indirect calls.</item>
+ <tag><c>xref:q(s, "{toolbar,debugger}:Mod of ME").</c></tag>
+ <item>A chain of module calls from <c>toolbar</c> to
+ <c>debugger</c>, if there is such a chain, otherwise
+ <c>false</c>. The chain of calls is represented by a list of
+ modules, <c>toolbar</c> being the first element and
+ <c>debugger</c>the last element.</item>
+ <tag><c>xref:q(s, "closure E | toolbar:Mod || debugger:Mod").</c></tag>
+ <item>All (in)direct calls from functions in <c>toolbar</c> to
+ functions in <c>debugger</c>.</item>
+ <tag><c>xref:q(s, "(Fun) xref -> xref_base").</c></tag>
+ <item>All function calls from <c>xref</c> to <c>xref_base</c>.</item>
+ <tag><c>xref:q(s, "E * xref -> xref_base").</c></tag>
+ <item>Same interpretation as last expression.</item>
+ <tag><c>xref:q(s, "E || xref_base | xref").</c></tag>
+ <item>Same interpretation as last expression.</item>
+ <tag><c>xref:q(s, "E * [xref -> lists, xref_base -> digraph]").</c></tag>
+ <item>All function calls from <c>xref</c> to <c>lists</c>, and
+ all function calls from <c>xref_base</c> to <c>digraph</c>.</item>
+ <tag><c>xref:q(s, "E | [xref, xref_base] || [lists, digraph]").</c></tag>
+ <item>All function calls from <c>xref</c> and <c>xref_base</c>
+ to <c>lists</c> and <c>digraph</c>.</item>
+ <tag><c>xref:q(s, "components EE").</c></tag>
+ <item>All strongly connected components of the Inter Call
+ Graph. Each component is a set of exported or unused local functions
+ that call each other (in)directly.</item>
+ <tag><c>xref:q(s, "X * digraph * range (closure (E | digraph) | (L * digraph))").</c></tag>
+ <item>All exported functions of the <c>digraph</c> module
+ used (in)directly by some function in <c>digraph</c>.</item>
+ <tag><c>xref:q(s, "L * yeccparser:Mod - range (closure (E |</c></tag>
+ <item></item>
+ <tag><c>yeccparser:Mod) | (X * yeccparser:Mod))").</c></tag>
+ <item>The interpretation is left as an exercise. </item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>Graph Analysis</title>
+ <p>The list <seealso marker="xref#representation">representation of graphs</seealso> is used analyzing direct calls,
+ while the <c>digraph</c> representation is suited for analyzing
+ indirect calls. The restriction operators (<c>|</c>, <c>||</c>
+ and <c>|||</c>) are the only operators that accept both
+ representations. This means that in order to analyze indirect
+ calls using restriction, the <c>closure</c> operator (which creates the
+ <c>digraph</c> representation of graphs) has to been
+ applied explicitly.
+ </p>
+ <p>As an example of analyzing indirect calls, the following Erlang
+ function tries to answer the question:
+ if we want to know which modules are used indirectly by some
+ module(s), is it worth while using the <seealso marker="xref#call_graph">function graph</seealso> rather
+ than the module graph? Recall that a module M1 is said to call
+ a module M2 if there is some function in M1 that calls some
+ function in M2. It would be nice if we could use the much
+ smaller module graph, since it is available also in the light
+ weight <c>modules</c><seealso marker="xref#mode">mode</seealso> of Xref servers.
+ </p>
+ <code type="erl">
+ t(S) ->
+ {ok, _} = xref:q(S, "Eplus := closure E"),
+ {ok, Ms} = xref:q(S, "AM"),
+ Fun = fun(M, N) ->
+ Q = io_lib:format("# (Mod) (Eplus | ~p : Mod)", [M]),
+ {ok, N0} = xref:q(S, lists:flatten(Q)),
+ N + N0
+ end,
+ Sum = lists:foldl(Fun, 0, Ms),
+ ok = xref:forget(S, 'Eplus'),
+ {ok, Tot} = xref:q(S, "# (closure ME | AM)"),
+ 100 * ((Tot - Sum) / Tot). </code>
+ <p>Comments on the code:
+ </p>
+ <list type="bulleted">
+ <item>We want to find the reduction of the closure of the
+ function graph to modules.
+ The direct expression for doing that would be
+ <c>(Mod)&nbsp;(closure&nbsp;E&nbsp;|&nbsp;AM)</c>, but then we
+ would have to represent all of the transitive closure of E in
+ memory. Instead the number of indirectly used modules is
+ found for each analyzed module, and the sum over all modules
+ is calculated.
+ </item>
+ <item>A user variable is employed for holding the <c>digraph</c>
+ representation of the function graph for use in many
+ queries. The reason is efficiency. As opposed to the
+ <c>=</c> operator, the <c>:=</c> operator saves a value for
+ subsequent analyses. Here might be the place to note that
+ equal subexpressions within a query are evaluated only once;
+ <c>=</c> cannot be used for speeding things up.
+ </item>
+ <item><c>Eplus | ~p : Mod</c>. The <c>|</c> operator converts
+ the second operand to the type of the first operand. In this
+ case the module is converted to all functions of the
+ module. It is necessary to assign a type to the module
+ (<c>:&nbsp;Mod</c>), otherwise modules like <c>kernel</c> would be
+ converted to all functions of the application with the same
+ name; the most general constant is used in cases of ambiguity.
+ </item>
+ <item>Since we are only interested in a ratio, the unary
+ operator <c>#</c> that counts the elements of the operand is
+ used. It cannot be applied to the <c>digraph</c> representation
+ of graphs.
+ </item>
+ <item>We could find the size of the closure of the module graph
+ with a loop similar to one used for the function graph, but
+ since the module graph is so much smaller, a more direct
+ method is feasible.
+ </item>
+ </list>
+ <p>When the Erlang function <c>t/1</c> was applied to an Xref
+ server loaded with the current version of OTP, the returned
+ value was close to 84&nbsp;(percent). This means that the number
+ of indirectly used modules is approximately six times greater
+ when using the module graph.
+ So the answer to the above stated question is that it is
+ definitely worth while using the function graph for this
+ particular analysis.
+ Finally, note that in the presence of unresolved calls, the
+ graphs may be incomplete, which means that there may be
+ indirectly used modules that do not show up.
+ </p>
+ </section>
+</chapter>
+