aboutsummaryrefslogtreecommitdiffstats
path: root/system/doc/reference_manual/macros.xml
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 /system/doc/reference_manual/macros.xml
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'system/doc/reference_manual/macros.xml')
-rw-r--r--system/doc/reference_manual/macros.xml211
1 files changed, 211 insertions, 0 deletions
diff --git a/system/doc/reference_manual/macros.xml b/system/doc/reference_manual/macros.xml
new file mode 100644
index 0000000000..a1ba182eff
--- /dev/null
+++ b/system/doc/reference_manual/macros.xml
@@ -0,0 +1,211 @@
+<?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 Preprocessor</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>macros.xml</file>
+ </header>
+
+ <section>
+ <title>File Inclusion</title>
+ <p>A file can be included in the following way:</p>
+ <pre>
+-include(File).
+-include_lib(File).</pre>
+ <p><c>File</c>, a string, should point out a file. The contents of
+ this file are included as-is, at the position of the directive.</p>
+ <p>Include files are typically used for record and macro
+ definitions that are shared by several modules. It is
+ recommended that the file name extension <c>.hrl</c> be used
+ for include files.</p>
+ <p><c>File</c> may start with a path component <c>$VAR</c>, for
+ some string <c>VAR</c>. If that is the case, the value of
+ the environment variable <c>VAR</c> as returned by
+ <c>os:getenv(VAR)</c> is substituted for <c>$VAR</c>. If
+ <c>os:getenv(VAR)</c> returns <c>false</c>, <c>$VAR</c> is left
+ as is.</p>
+ <p>If the filename <c>File</c> is absolute (possibly after
+ variable substitution), the include file with that name is
+ included. Otherwise, the specified file is searched for in
+ the current working directory, in the same directory as
+ the module being compiled, and in the directories given by
+ the <c>include</c> option, in that order.
+ See <c>erlc(1)</c> and <c>compile(3)</c> for details.</p>
+ <p>Examples:</p>
+ <pre>
+-include("my_records.hrl").
+-include("incdir/my_records.hrl").
+-include("/home/user/proj/my_records.hrl").
+-include("$PROJ_ROOT/my_records.hrl").</pre>
+ <p><c>include_lib</c> is similar to <c>include</c>, but should not
+ point out an absolute file. Instead, the first path component
+ (possibly after variable substitution) is assumed to be
+ the name of an application. Example:</p>
+ <pre>
+-include_lib("kernel/include/file.hrl").</pre>
+ <p>The code server uses <c>code:lib_dir(kernel)</c> to find
+ the directory of the current (latest) version of Kernel, and
+ then the subdirectory <c>include</c> is searched for the file
+ <c>file.hrl</c>.</p>
+ </section>
+
+ <section>
+ <title>Defining and Using Macros</title>
+ <p>A macro is defined the following way:</p>
+ <code type="none">
+-define(Const, Replacement).
+-define(Func(Var1,...,VarN), Replacement).</code>
+ <p>A macro definition can be placed anywhere among the attributes
+ and function declarations of a module, but the definition must
+ come before any usage of the macro.</p>
+ <p>If a macro is used in several modules, it is recommended that
+ the macro definition is placed in an include file.</p>
+ <p>A macro is used the following way:</p>
+ <code type="none">
+?Const
+?Func(Arg1,...,ArgN)</code>
+ <p>Macros are expanded during compilation. A simple macro
+ <c>?Const</c> will be replaced with <c>Replacement</c>.
+ Example:</p>
+ <code type="none">
+-define(TIMEOUT, 200).
+...
+call(Request) ->
+ server:call(refserver, Request, ?TIMEOUT).</code>
+ <p>This will be expanded to:</p>
+ <code type="none">
+call(Request) ->
+ server:call(refserver, Request, 200).</code>
+ <p>A macro <c>?Func(Arg1,...,ArgN)</c> will be replaced with
+ <c>Replacement</c>, where all occurrences of a variable <c>Var</c>
+ from the macro definition are replaced with the corresponding
+ argument <c>Arg</c>. Example:</p>
+ <code type="none">
+-define(MACRO1(X, Y), {a, X, b, Y}).
+...
+bar(X) ->
+ ?MACRO1(a, b),
+ ?MACRO1(X, 123)</code>
+ <p>This will be expanded to:</p>
+ <code type="none">
+bar(X) ->
+ {a,a,b,b},
+ {a,X,b,123}.</code>
+ <p>It is good programming practice, but not mandatory, to ensure
+ that a macro definition is a valid Erlang syntactic form.</p>
+ <p>To view the result of macro expansion, a module can be compiled
+ with the <c>'P'</c> option. <c>compile:file(File, ['P'])</c>.
+ This produces a listing of the parsed code after preprocessing
+ and parse transforms, in the file <c>File.P</c>.</p>
+ </section>
+
+ <section>
+ <title>Predefined Macros</title>
+ <p>The following macros are predefined:</p>
+ <taglist>
+ <tag><c>?MODULE</c></tag>
+ <item>The name of the current module.</item>
+ <tag><c>?MODULE_STRING</c>.</tag>
+ <item>The name of the current module, as a string.</item>
+ <tag><c>?FILE</c>.</tag>
+ <item>The file name of the current module.</item>
+ <tag><c>?LINE</c>.</tag>
+ <item>The current line number.</item>
+ <tag><c>?MACHINE</c>.</tag>
+ <item>The machine name, <c>'BEAM'</c>.</item>
+ </taglist>
+ </section>
+
+ <section>
+ <title>Flow Control in Macros</title>
+ <p>The following macro directives are supplied:</p>
+ <taglist>
+ <tag><c>-undef(Macro).</c></tag>
+ <item>Causes the macro to behave as if it had never been defined.</item>
+ <tag><c>-ifdef(Macro).</c></tag>
+ <item>Evaluate the following lines only if <c>Macro</c> is
+ defined.</item>
+ <tag><c>-ifndef(Macro).</c></tag>
+ <item>Evaluate the following lines only if <c>Macro</c> is not
+ defined.</item>
+ <tag><c>-else.</c></tag>
+ <item>Only allowed after an <c>ifdef</c> or <c>ifndef</c>
+ directive. If that condition was false, the lines following
+ <c>else</c> are evaluated instead.</item>
+ <tag><c>-endif.</c></tag>
+ <item>Specifies the end of an <c>ifdef</c> or <c>ifndef</c>
+ directive.</item>
+ </taglist>
+ <note>
+ <p>The macro directives cannot be used inside functions.</p>
+ </note>
+ <p>Example:</p>
+ <code type="none">
+-module(m).
+...
+
+-ifdef(debug).
+-define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE,?LINE,X])).
+-else.
+-define(LOG(X), true).
+-endif.
+
+...</code>
+ <p>When trace output is desired, <c>debug</c> should be defined
+ when the module <c>m</c> is compiled:</p>
+ <pre>
+% <input>erlc -Ddebug m.erl</input>
+
+or
+
+1> <input>c(m, {d, debug}).</input>
+{ok,m}</pre>
+ <p><c>?LOG(Arg)</c> will then expand to a call to <c>io:format/2</c>
+ and provide the user with some simple trace output.</p>
+ </section>
+
+ <section>
+ <title>Stringifying Macro Arguments</title>
+ <p>The construction <c>??Arg</c>, where <c>Arg</c> is a macro
+ argument, will be expanded to a string containing the tokens of
+ the argument. This is similar to the <c>#arg</c> stringifying
+ construction in C.</p>
+ <p>The feature was added in Erlang 5.0/OTP R7.</p>
+ <p>Example:</p>
+ <code type="none">
+-define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])).
+
+?TESTCALL(myfunction(1,2)),
+?TESTCALL(you:function(2,1)).</code>
+ <p>results in</p>
+ <code type="none">
+io:format("Call ~s: ~w~n",["myfunction ( 1 , 2 )",m:myfunction(1,2)]),
+io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).</code>
+ <p>That is, a trace output with both the function called and
+ the resulting value.</p>
+ </section>
+</chapter>
+