autodoc.git/
traditional_manual/
chapter_21.html
Branch:
Tag:
Non-build tags
All tags
No tags
2005-06-10
2005-06-10 17:16:04 by Henrik Grubbström (Grubba) <grubba@grubba.org>
5c46d0c9682458a967d9b3562c596de356ab3826 (
1184
lines) (+
1119
/-
65
)
[
Show
|
Annotate
]
Branch:
8.0
Added the compatibility chapter.
Rev: refdoc/structure/traditional.xml:1.23
1:
<!doctype html><html><head><title>Pike Reference Manual</title> <meta charset='utf-8'></head>
-
<body><dl><dt><h1 class='header'>21. Pike
BNF
</h1></dt><dd><
dl
>
-
<dt><a
href
='
index.html
'>
Table of Contents
</a>
</dt>
-
<
dt><a
href
='
chapter_1.html
'>1.
Introduction
</
a
></dt>
-
<dd><
a
href
='
chapter_1.html#1
'>1.1.
Overview
</
a
></
dd
>
-
<dd><a
href='chapter_1
.
html#2'>1
.
2.
The
history
of
Pike
</
a
></
dd
>
-
<
dd
><
a href='chapter_1.html#3'
>
1.3.
A
comparison
with
other
languages
</
a
></
dd
>
-
<
dd
><
a
href=
'
chapter_1
.
html#4
'>
1
.
4
.
What
is
Pike
</
a
></
dd
>
-
<
dd
><
a
href='chapter_1
.
html#5'>1.5.
Pike
License
</
a
></dd>
-
<dt><
a
href
='
chapter_2.html
'>2.
Control Structures
</
a
></dt>
-
<dd><
a
href='chapter_2
.
html#1'>2
.
1.
Conditions
</
a
><
/dd
>
-
<
dd
><
a
href='chapter_2
.
html#2'>2
.
2
.
Loops
</
a
></
dd
>
-
<
dd
><
a
href='chapter_2
.
html#3'>2
.
3
.
Breaking
out
of
loops
</
a
></
dd
>
-
<
dt
><a
href='chapter_3
.
html'>3
.
Data
types
</
a
></
dt
>
-
<
dd
><a
href='chapter_3
.
html#
1
'>
3.
1.
Basic
types
</
a
></
dd
>
-
<
dd
><a
href='chapter_3
.
html#2'>3
.
2
.
Pointer
types
</
a
></
dd
>
-
<
dd
><
a
href='chapter_3.html#3'
>
3.3.
Sharing
data
</
a
></
dd
>
-
<
dd
><
a
href='chapter_
3
.html#4'>3.4.
Variables
</
a
></dd>
-
<dt><
a
href
='
chapter_4.html
'>
4
.
Operators
</
a
></dt>
-
<dd><a
href='chapter_4
.
html#1'>4
.
1.
Arithmetic
operators
</
a
></
dd
>
-
<
dd
><
a
href=
'
chapter_4
.
html#2'>4
.
2.
Comparison
operators
</
a
><
/dd
>
-
<
dd
><
a
href=
'
chapter_4.html#3
'
>4
.
3.
Logical
operators
</
a
></
dd
>
-
<dd><
a
href
='
chapter_4.html#4
'>
4
.4.
Bitwise/set
operators
</
a
></
dd
>
-
<dd><a
href='chapter_4
.
html#5'
>
4
.
5.
Indexing
</
a
></
dd
>
-
<
dd
><a
href='chapter_4
.
html#6
'
>4
.
6.
The
assignment
operators
</
a
></
dd
>
-
<
dd
><a
href=
'
chapter_4.html#7'
>
4.7.
The
rest
of the
operators
</
a
><
/dd
>
-
<
dd
><a
href='chapter_4.html#8'>4.8.
Operator
precedence
</
a
><
/dd
>
-
<
dd
><
a
href='chapter_4
.
html#9'
>
4.9.
Operator
functions
</a></
dd
>
-
<dt><
a
href
='
chapter_5.html
'>5.
Preprocessor
</
a
></dt>
-
<dd><a
href=
'
chapter
_
5.html#1
'
>5.1.
Charset
Heuristics
</
a
></dd>
-
<
dd
><a
href
='
chapter_5.html#
2'>
5
.2.
Code
Normalization
</
a
></
dd
>
-
<dd><a
href='chapter_5
.
html#3'
>
5
.
3
.
Defines
and
Macros
</
a
><
/dd
>
-
<dd><
a
href
='
chapter_5.html#4
'>
5
.
4
.
Preprocessor
Directives
</
a
></
dd
>
-
<dd><
a href='chapter_5.html#5'
>
5.5.
Predefined
defines
</
a
></
dd
>
-
<
dt
><
a
href='chapter_6
.
html'
>
6
.
Special
Functions
</
a
><
/dt
>
-
<
dd
><a
href='chapter_6
.
html#1'>6
.
1
.
sscanf<
/a></
dd
>
-
<dd><
a
href
='
chapter_6.html#2
'>
6
.2.
catch
</
a
></dd>
-
<
dd
><
a
href='chapter
_
6
.
html#3'>6
.
3
.
gauge
</
a
><
/dd
>
-
<
dd
><
a
href='chapter_6
.
html#4'>6
.
4
.
typeof
</
a
></
dd
>
-
<
dt
><a
href='chapter_7
.
html'>7
.
Hilfe
</
a
></
dt
>
-
<
dd
>
<
a
href='chapter_7
.
html#1
'>
7
.
1
.
Basic
operations
</
a
></
dd
>
-
<
dd
>
<a
href='chapter_7
.
html#2'
>
7
.
2
.
Commands<
/a></
dd
>
-
<
dd
>
<
a
href='chapter_7
.
html#3'>7
.
3
.
Bugs
and
possible
improvements
</a></
dd
>
-
<
dt
><a
href='chapter_8
.
html'>8
.
LFUN
</
a
></
dt
>
-
<
dt
>
<a
href='chapter
_
9
.
html
'>
9
.
I
/
O
</
a
></
dt
>
-
<
dt
>
<a
href=
'
chapter_10
.
html'
>
10
.
Specific
Datatype
Modules
</
a
><
/dt
>
-
<
dt
><
a
href='chapter_11
.
html'>11
.
Parsers
</
a
></
dt
>
-
<
dt
>
<
a
href='chapter
_
12
.
html'
>
12
.
Image
Module
</
a
></
dt
>
-
<dt><a
href
='
chapter_13.html
'>
13
.
Protocols
</
a
></dt>
-
<
dt
><
a
href='chapter_14
.
html'
>
14
.
Database
Access
</
a
></
dt
>
-
<
dt
><
a
href='chapter_15
.
html'
>
15.
Graphic
User
Interface
</
a
><
/dt
>
-
<
dt
><a
href='chapter_16
.
html'>16
.
3D
Vector
Graphics
</
a
></
dt
>
-
<
dt
><
a
href='chapter_17
.
html'>17
.
The rest
</
a
></
dt
>
-
<dt><
a
href
='
chapter_18.html
'>
18
.
Writing
Pike
Modules
</
a
></dt>
-
<dd><
a
href='chapter_18
.
html#1'
>
18
.
1
.
Writing
Modules
in
Pike
</
a
></
dd
>
-
<
dd
><
a
href='chapter_18
.
html#2'>18.2.
Writing
Modules
in
C
</
a
></
dd
>
-
<
dd
><a
href='chapter_18.html#3'
>
18
.
3
.
Special
Module
Variables
and
functions
</
a
></
dd
>
-
<
dt
>
<
a
href=
'
chapter_19.html'
>
19
.
Pike
Test
Suite
</
a
></
dt
>
-
<
dd
>
<a
href='chapter_19
.
html#1'
>
19
.1.
Running
Tests
</
a
></
dd
>
-
<
dd
>
<a
href='chapter_19
.
html#2'>19
.
2
.
Writing
New
Tests
</
a
><
/dd
>
-
<
dt
><
a
href='chapter_20
.
html'
>
20
.
Pike
AutoDoc
markup
</
a
></
dt
>
-
<
dd
><
a
href='chapter_20
.
html#1'
>
20
.
1
.
Syntax
</
a
></
dd
>
-
<
dd
><
a
href='chapter
_
20.html#2'
>
20
.
2
. Pike
autodoc
inlining
</
a
></
dd
>
-
<
dd
><a
href
=
'chapter_20
.
html#
3
'>20
.3. Pike
autodoc
tags<
/a
><
/
dd>
-
<dt><
a
href
=
'chapter_21
.
html'>21
. Pike
BNF<
/a
>
</
dt
>
-
</
dl
></dd></dl></body></html>
+
<body><dl><dt><h1 class='header'>21. Pike
AutoDoc markup
</h1></dt><dd><
/dd
>
+
<dt><a
name
='
1
'></a>
+
<
h2
class
='
header
'>
21.
1.
Syntax
</
h2
></dt>
+
<dd><
/dd><dt><h3
class
='
header
'>
21.
1.1.
Line orientation
</
h3
></
dt
><dd><
p>The markup is line oriented. If you need to write
a
line which is very
+
long, it can be broken into several lines
.
A trailing @ on the line
+
indicates that it continues on the next line
. The
@
and
the newline
+
character will be discarded, and the lines merged. Thus:
</
p
><
p><
/
p
>
<pre>
+
//! @variable thisVariableNameIsSoLong@
+
//!YouJustCantBelieveIt
+
<
/pre
><
p
>
</p>
+
<p>will
appear
to
the
parser
as:
</
p
><
p><
/
p
>
<pre>
+
//! @variable thisVariableNameIsSoLongYouJustCantBelieveIt
+
<
/pre
><
p></p>
+
<p>This
is sometimes necessary because keywords that take parameters
+
expect all the parameters to appear on the same line and treat the end
+
of the line as the end of the parameter list.</p><p>The character
'
\r' is also discarded
.
The same applies to all other
+
non-printable and control characters except for
'
\n' and '\t'.</p
>
<p>In text (see the nonterminal 'text' in the grammar at the end of this
+
file), a blank line with surrounding non-blank lines will give a
+
paragraph break
.
Thus:</p><p></p><pre>
+
//! - I love you, said Danny
.
+
//!
+
//! - You have no right to come here after what you did to
+
//! my little dog, screamed Penny in despair.
+
</
pre
><
p><
/
p
>
+
<
p
>
will generate the following XML:
<
/p><p><pre>
+
<p> - I love you, said Danny
.
</p>
+
<p> - You have no right to come here after what you did to
+
my little dog, screamed Penny in despair.</p>
+
</
pre
></
p></
dd><dt><
h3
class
='
header
'>
21.1.
2.
Keywords
</
h3
></dt><dd><
p>Keywords
always begin with an at-sign: @
.
A @ is quoted by writing two
+
of them: @@
.
There are four types of keywords (the keywords in []'s
+
are examples of keywords of the different types):
</
p
><
ol
>
+
<
li
><
p>
Meta keywords [@decl, @class, @endclass, @module and @endmodule]
+
Must stand alone on one line, preceded only by whitespace
.
These are
+
not really part of the markup
.
They must come before any text or
+
other keywords in the doc block
.
They provide information about what
+
is being documented etc. and do not result in any text in the
+
documentation. Meta keywords have keyword specific parameter
+
syntaxes.
</
p
></
li
>
+
+
<
li
><
p>
Delimiter keywords [@param, @member, @item, @note,
...
]
+
Must
stand
alone
on one line, preceded only by whitespace. These are
+
keywords that begin a section inside their block. They have no end
+
marker, but rather the section ends when the next delimiter keyword
+
on the same level is found. Can have parameters.
</
p
></
li
>
+
+
<
li
><
p> Block/endblock keywords [@dl - @enddl, @mapping - @endmapping, ...]
+
Must stand alone on one line, preceded only by whitespace. These open
+
or close
a
block
.
If a block is started with @foo, it must end with a
+
matching @endfoo
.
The
lines inside the block can be divided into
+
sections by using delimiter keywords. The start keyword can have
+
parameters, but the corresponding end keyword can not.
</
p
></
li
>
+
+
<
li
><
p> Short markup keywords [@ref{..@}, @i{..@}, ...]
+
These are used in the text to perform cosmetic tasks, for example
+
changing text to italic (@i), teletype(@tt) or marking
a
word as a
+
reference to a pike entity (@ref)
.
They can be nested, but a short
+
markup keyword can not contain a keyword of types
1
-
3.
They
begin
+
with @keyword{ and end with @}.
</
p
></
li
>
+
+
<
li
><
p> The magic keyword @xml{ ... @}
+
This is
a
special keyword that provides an escape to XML
.
All ordinary
+
text inside it is passed unquoted to the output
.
However, the short
+
markup keywords are still valid and may be used inside it, and thus
+
@ must still be quoted with @@
.
<
and > must also be quoted unless
+
the intention really is to write XML. For example:
</
p
>
+
+
<
example>
+
/
/! He is so @xml{<i>italic</i> and @b{bold@}!@}!!
+
</example
>
+
+
<
p
>
will generate the following XML:
<
/p>
+
+
<p
>
<pre>
+
He is so <i>italic</i> and <b>bold</b>!!!
+
</
pre
></
p
>
</li>
+
<
/ol
><
p>NOTA
BENE: Delimiter keywords (2) and block keywords (
3
) must stand
+
alone (with their parameters, if any) on one line
.</
p
></dd><dt><
h3
class
='
header
'>
21
.
1.3.
Delimiter keyword grouping
</
h3
></dt><dd><
p>Delimiter keywords that indicate
a
new section inside the block can be
+
grouped together in the interest of not writing the same docstring for
+
multiple parameters etc
.
Delimiters are grouped if they appear on
+
consecutive lines. For example, when documenting a method:</p
>
<p></p><pre>
+
//! @decl int dist(int x, int y)
+
//! Calculates the distance
.
+
//! @param x
+
//! @param y
+
//! The coordinates of the vector.
+
</
pre
><
p><
/
p
>
+
<
p
>
Above,
the two @param
'
s x and y are grouped together and share the
+
same docstring: "The coordinates of the vector
.
"
.
It
is an error to
+
try to group together different keywords:
</
p
><
p><
/
p
><
pre
>
+
//! Error, can
'
t group @note and @param:
+
//! @param x
+
//! @note
+
//! Don
'
t use this function
.
At all
.
Ever.
+
</
pre
><
p><
/
p
>
+
<
/
dd><
dt><h3
class
='
header
'>
21
.
1.
4.
Keyword
parameters
</
h3
></
dt
><dd><
p>After the leading @keyword (that may be preceded only by whitespace)
+
on the line, the rest of the line is interpreted as
a
parameter list
.
+
The syntax of this parameter list can be different depending on the
+
keyword:</p
>
<ol>
+
<li><p> Special keyword parameter list syntax
+
Here the parameters can be parsed according to Pike syntax or in
+
some other way
.
Examples of keywords that use these kinds of special
+
syntaxes are all the meta keywords, @member and @elem
.</
p
></
li
>
+
+
<
li
><
p> Default parameter list syntax
+
The meaning of parameters is determined by the order in which they
+
appear, much like the arguments in
a
unix shell command line - hence
+
they are not named as in HTML or XML
.
Parameters are separated by
+
whitespace. If you wish to have a parameter string with whitespace in
+
it, you must surround the string with a pair of
'
or "
.
When
the
+
quoting character itself is in the string, a duplication is used to
+
quote it:
</
p>
+
+
<example>
+
//! @question "He is
a
""swapper""?!"
+
</example
>
+
+
<
p>However, if your parameter contains only one of ' and ", then it is
+
smarter to choose the other one as the quouting character:<
/
p
>
+
+
<
example
>
+
//! @question 'He is
a
"swapper"?!
'
+
</example
>
+
+
<p>It
is
an error not to end a quote before the end
of the
line:
</
p
>
+
+
<
example>
+
/
/! @wrong "Aww, come on now, this worked fine in C64 basic!
+
</example
>
+
+
<
p
>
If
a
quoted parameter is too long to fit in one line, use the @ at
+
the end of the line to merge it with the following:</p
>
+
+
<example>
+
//! @right "Oh, joy! Now I can make my parameters just as@
+
//! long as I want them!"
+
</
example
>
+
+
<
p>The parameters are not parsed so you can not have markup inside
+
them. Pike style quoting is not used either, which means that if
+
you write:<
/
p
>
+
+
<
example
>
+
//! @look "\n"
+
<
/example>
+
+
<p
>
The
parameter
will be a string with two characters, a backslash
+
followed by the letter n.
</
p
></
li
>
+
<
/ol></dd><
dt><
h3
class
='
header
'>
21.1.
5.
Grammar
</
h3
></dt><dd><
p>Here comes
a
BNF-ish grammar for documentation blocks. Note that
+
before the parsing of the block, all lines ending with a @ will be
+
merged with the next line (see (a) above)</p><p><pre>
+
docblock:
+
metaline*, blockbody
+
+
metaline:
+
start_of_line, white_space*, metakeyword, any_char_but_newline,
+
end_of_line
+
+
blockbody:
+
section?, (delimiter+, section)*, delimiter?
+
+
delimiter:
+
start_of_line, white_space*, delimiterkeyword, parameterlist,
+
end_of_line
+
+
section:
+
(text|block)+
+
+
block:
+
blockbegin, blockbody, blockend
+
+
blockbegin:
+
start_of_line, white_space*, blockkeyword, parameterlist,
+
end_of_line
+
+
blockend:
+
start_of_line, white_space*, blockkeyword, white_space*, end_of_line
+
+
parameterlist:
+
white_space*, (parameter, white_space+)*
+
+
parameter:
+
qoutedparameter | any_char_but_white_space+
+
+
quotedparameter:
+
(
'
"', (any
_
char_but_new_line_or_" |
'
""'),
'"')
+
| ('\'', (any_char_but_new_line_or_' | '\'\''), '\'')
+
+
text:
+
(character|shortmarkup|xmlescape)+
+
+
xmlescape:
+
'@xml{', any_char_sequence_not_containing_@}, '@}'
+
+
character:
+
any_char_but_@ | '@@'
+
+
shortmarkup:
+
shortmarkupkeyword, '{', text, '@}'
+
+
metakeyword, blockkeyword, delimiterkeyword, shortmarkupkeyword:
+
keyword
+
+
keyword:
+
'@', alpha_char+
+
+
endblockkeyword:
+
'@end', alpha_char+
+
+
white_space:
+
' ' | '\t'
+
</
pre
></
p></
dd>
+
<
dt
><a
name
='2'>
</a>
+
<h2 class='header'>21
.2.
Pike
autodoc inlining
</
h2
></
dt
>
+
<dd><
p>The autodoc extractor works either in C mode or in Pike mode. The
+
reason why the two modes are not the same is that they perform two
+
very different tasks. The C mode only has to find comments in the
+
file, and ignores the surrounding code totally, while the Pike mode on
+
the other hand is supposed to be smarter and distill
a
lot of
+
information from the Pike code that surrounds the comments
.
</p
>
<p>Both work at the file level
.
That makes it easy to use for example
+
"make" to generate documentation for the source tree
.
Another
benefit
+
is
that the generation will not have to reparse all of the tree if
+
only one source file is changed.
</
p
><
p
>
For Pike module trees, the extractor can recurse through the file tree
+
on its own, but for C files, where the directory structure gives
+
insufficient cues about what is what, there must be make targets set
+
up manually. All generated XML files can then be merged together into
+
the final Pike namespace.
<
/p></
dd><
dt><h3
class
='
header
'>
21
.
2
.
1.
C
files
</
h3
></
dt
><dd><
p>In
C files, the doc comments look like:</p
>
<p></p><pre>
+
/*! yadda yadda
+
*! yadda yadda yadda
+
*/
+
</
pre
><
p><
/
p
>
+
<
p
>
Note
that only lines that start with *! count, so above are only two
+
doc lines
.
Any whitespace before the leading *! is skipped, so that
+
the lines can be indented freely.</p
>
<p>In the C files, no parsing of the surrounding code is done
.
The
+
context
lies completely in the doc comments themselves, and the target
+
of the doc comment is determined by special meta keywords that are not
+
really part of the doc blocks, but rather modifiers that tell which
+
Pike entity the doc is about.
</
p
><
p><
/
p
><
pre
>
+
/*! @module Foo
+
*! ... doc for the Foo module ...
+
*! ... */
+
+
/*! @decl int
a
()
+
*!
...
doc for the method Foo.a() ...
+
*! .... */
+
+
/*! @class Bar
+
*! ... doc for the class Foo.Bar ...
+
*! ... */
+
+
/*! @decl mapping(string:string) userprefs()
+
*! ... doc for the method Foo.Bar->userprefs() ...
+
*! ... */
+
+
/*! @decl int a
+
*! @decl int b
+
*! ... doc for the variables Foo.Bar->a and Foo.Bar->b ...
+
*! ... */
+
+
/*! @endclass */
+
+
/*! @endmodule */
+
</
pre
><
p><
/
p
>
+
<
p>The @module and @class too keywords are to work like segment
+
directives in assembler source files. That is, you can have "@module
+
foo" in several C files, if the module source is spread over multiple
+
files. However, if you write doc for the module itself in several
+
places, an error will be triggered.</p></
dd><
dt><h3
class
='
header
'>
21
.2.
2.
Pike files
</
h3
></
dt><
dd>
<p>Doc comments look like:</p><p></p><pre>
+
//! yadda yadda yadda
+
//! yadda yadda
+
<
/pre
><
p></p>
+
<p>To
be considered one doc block, the comments must be separated only by
+
whitespace and
_
one_ "\n", that is they have to be on adjacent lines
+
in the code
.
Each doc block in the Pike code has one or more targets;
+
the Pike entities (modules, classes, variables etc
.
) that the doc
+
block is documenting
.
The target of a doc comment is the coherent
+
block of declarations adjacent to (immediately before or after) it in
+
the code, without intervening blank lines. Examples:
</
p
><
p><
/
p
><
pre
>
+
//! Doc for alpha
+
int alpha()
+
{
+
return 4711;
+
}
+
+
static int undocumented;
+
+
//! Error! This doc block has no destination!
+
+
int beta;
+
//! Doc for beta
+
+
//! Doc for gamma, delta, and epsilon
+
int gamma, delta;
+
float epsilon;
+
+
//! Error here!
+
int zeta;
+
//! ambiguous which doc to associate with zeta
.
+
+
int eta;
+
//! Error here too! ambiguous which variable is documented
.
+
int theta;
+
+
//! Doc for two methods
.
This is so UGLY! We strongly recommend
+
//! using the decl keywords instead to accomplish this effect.
+
int methodOne()
+
{
+
...
+
}
+
int methodTwo()
+
{
+
...
+
}
+
+
//! However, it can be useful sometimes, for really short methods:
+
int very_short() { return 4711; }
+
int even_shorter() { return 0; }
+
</
pre
><
p><
/
p
>
+
<
p
>
In Pike files, you can not use @class or @module to tell which module
+
or class you are in. To document a class, you simply write:
<
/p><p></p><pre>
+
//! Doc for the class
+
class CheeseMaker
+
{
+
//! You can even document inherits!
+
inherit Earth : earth;
+
+
//! Doc for CheeseMaker->
a
()
+
int a()
+
{
+
..
.
+
}
+
+
void create(string s) { ... }
+
}
+
</
pre
><
p><
/
p
>
+
<
p
>
The parser will automatically identify
a
()
as a member method of the
+
class CheeseMaker, and will detect that Earth is inherited by
+
CheeseMaker
.
If a class has no documentation comment, it
'
s internals
+
will not be examined, thus it is an error if a class contains
+
documentation comments but is itself undocumented:</p
>
<p></p><pre>
+
class a()
+
{
+
//! @decl foo
+
//!
..
.
doc
for foo ...
+
}
+
</
pre
><
p><
/
p
>
+
<
p
>
A
special inlining case is that of functions and classes
.
When documenting
+
these, the doc comment can be put between the head of the function/class,
+
and the opening "{", like this:</p
>
<p></p><pre>
+
class Roy
+
//! Documentation for Roy
+
{
+
..
..
+
}
+
+
int un_randomize(int x)
+
//! This function takes a random number, and transforms it into
+
//! a predictable number.
+
{
+
return x = 4711;
+
}
+
</
pre
><
p><
/
p
>
+
<
p
>
If
a
doc block is the first in a file, and it has no target, then it
+
is treated as doc for the file (or rather: the module/class that the
+
file compiles into) itself
.
In any other case it is an error to have a
+
targetless doc block
.
A target can also be set with the @decl meta
+
keyword
.
If
a
doc
comment begins with some @decl keywords, these
+
@decl's act just like real declarations standing next to the doc.
+
Thus:
</
p><p></p><pre>
+
//! @decl int
a
(int x)
+
//! @decl int b(int x)
+
//! Here is some doc for these functions....
+
</pre
><
p><
/
p
>
+
<
p
>
is autodocwise equivalent to:
<
/p><p></p><pre>
+
//! Here is some doc for these functions....
+
int
a
(int
x)
+
{
+
..
...
+
}
+
int b(int x)
+
{
+
.....
+
}
+
</
pre
><
p><
/
p
>
+
<
p
>
In
_
one_ case it is legal to have both an adjacent declaration and
+
the @decl keyword at the block beginning
.
That is when you document
+
"polymorph" methods. Then the adjacent declaration must be a method,
+
and all @decl
'
s must be methods that have the same name as the real
+
method:</p
>
<p></p><pre>
+
//! @decl float cube(float x)
+
//! @decl int cube(int x)
+
//! Gives x**3
.
+
/
/! @param x
+
//! The number to cube.
+
int|float cube(int|float x)
+
{
+
....
+
}
+
</
pre
><
p><
/
p
>
+
<
p
>
The
real method prototype is discarded in favour to the @decl
'
ed
+
variants, who will be shown in the documentation instead
.
</p
>
<p>One problem that is unsolved so far is how to handle #if
.
.
#else
..
+
#endif
constructions. The approach so far has been to ignore
+
preprocessor directives totally. For example, the parser does not
+
handle:
</
p
><
p><
/
p
>
<pre>
+
#ifdef MALE
+
int bertil()
+
#else
+
int berit()
+
#endif
+
{
+
... body ...
+
}
+
<
/pre
><
p></p>
+
<p>It
a
portion of the code is unextractable because it contains too much
+
preprocessor macros and stuff, you can make the extractor skip it by using
+
@ignore:</p
>
<p></p><pre>
+
//! @ignore
+
+
HERE_ARE_SOME_STRANGE_THINGS
+
#ifdef A
+
A
+
#endif
+
+
//! @endignore
+
</
pre
><
p><
/
p
>
+
<
p
>
All
@ignore-@endignore sections of the file are removed before any extraction
+
is done, so they can cross class boundaries and the like
.
You can nest @ignore
+
inside eachother. Another application for @ignore is to hide actual class
+
boundaries from the extractor:</p
>
<p></p><pre>
+
//! @ignore
+
class C {
+
//! @endignore
+
+
//! To the parser, this function appears to be on the top level
+
int f() {
.
..
}
+
+
//! @ignore
+
}
+
//! @endignore
+
</
pre
><
p><
/
p
>
+
<
/dd>
+
<
dt><a
name
='
3
'>
</a>
+
<h2 class='header'>21
.
3.
Pike autodoc tags
</
h2
></dt>
+
<
dd
><
p>We
have defined some different categories of markup, each with its own
+
semantics
.
Seen from the parser, there are two main construct levels:</p
>
<ul>
+
<li><p> The "what-are-we-documenting level" constructs; @decl for Pike files
+
and @module, @endmodule, @class and @endclass on top of that for C
+
files
.
These
are the meta level tags covered in section a).
</
p
></
li
>
+
+
<
li
><
p>
Inside-of-comment level constructs for documentation markup,
+
covered in sections b), c) and d)
.
</p
>
</li>
+
</ul><p>All
markup
can
also be divided into categories based on their look
+
and semantics; there are three categories here (with examples):
</
p
><
ul
>
+
<
li
><
p> Grouping constructs that mark the opening/closing of
a
section of
+
some sort (@mapping/@endmapping, @dl/@enddl, @module/@endmodule)
.
+
Most of these not already covered by secion a) appear in b).</p
>
</li>
+
+
<li><p>
subdividers
that
break up an outer grouping construct into
+
subsections (@member, @item, @param)
</
p
></
li
>
+
+
<
li
><
p>
short text markup constructs that basically map to XML containers
+
(@i{
..
.@},
@ref{...@})
</
p
></
li
>
+
<
/ul></dd><
dt><
h3
class
='
header
'>
21
.
3.1.
Meta
level
tags
</
h3
></dt><dd><
p>These
tags all serve the purpose of denoting what pike entities your
+
comments should be tied to
.
This is particularly needed in (and in
+
part only applies to) C files, where the autodoc extractor does not
+
try to interpret and parse class and method definitions.</p
>
<p><pre>
+
Keyword: @module
+
Legal for: C files only (neither needed nor legal for Pike files)
+
Arguments: (the last segment of) the module name (ie no "
.
" allowed)
+
</pre></p><p>Example: To document the module Parser
.
XML
module,
you
need
two
+
consecutive module tags:
</
p
><
p><
/
p
>
<pre>
+
/*! @module Parser */
+
/*! @module XML */
+
<
/pre
><
p></p>
+
<p>A
@module keyword sets the scope of documentation comments following
+
it
.
@module
tags
nest, as shown
in
the example above, and must be
+
ended with a matching number of @endmodule tags, as in:
</
p
><
p><
/
p
>
<pre>
+
/*! @endmodule XML */
+
/*! @endmodule Parser */
+
<
/pre
><
p></p>
+
<p>A @module keyword may also have
a
text child documenting the module
+
itself:</p
>
<p></p><pre>
+
/*! @module Parser
+
*!
+
*! The common roof under which parsers of various kinds, such as
+
*! @[Parser
.
XML], @[Parser
.
Pike]
and
@[Parser.C]
are
housed.
+
*/
+
</
pre
><
p><
/
p
>
+
<
p
>
There are two special @module targets available; the "predef::" module
+
and the "lfun::" module. The predef:: module, although more of
a
scope
+
than a module, contains the definitions for all methods in Pike
'
s
+
predef:: scope, as in:</p
>
<p></p><pre>
+
/*! @module predef::
+
*! @decl int equal(mixed a, mixed b)
+
*! This function checks if the values @[a] and @[b] are equal
.
+
*!
@endmodule
+
*/
+
</
pre
><
p><
/
p
>
+
<
p
>
The
"lfun::" module scope does not legally exist in Pike, but it
+
houses the docs for all lfuns (the virtual methods for fulfilling the
+
Pike object API)
.
An example:</p
>
<p></p><pre>
+
/*! @module lfun::
+
*! @decl int(0
.
.
1
) `!=(mixed arg1, mixed arg2, mixed
.
..
extras)
+
*! The inequality operator.
+
*! @endmodule
+
*/
+
</
pre
><
p><
/
p
>
+
<
p
>
This
also means that referencing (via @ref{
...
@}
or
@[...])
the lfun
+
documentation strings can be done using @[lfun::`!=] and the like, as
+
can predefs via @[predef::sort()] et cetera.
</
p
><
p
>
<pre>
+
Keyword: @endmodule
+
Legal for: C files only (neither needed nor legal for Pike files)
+
Arguments: (the last segment of) the module name (optional)
+
<
/pre
>
>
<
/p><p>When
the optional argument to @endmodule is given (for code clarity),
+
the extractor will verify that the module scope you close was indeed
+
the one you opened, as in the @module example above
.
The following
+
would trigger an error:</p
>
<p></p><pre>
+
/*! @module Parser
+
*! @module XML */
+
+
/*!
.
..
some
autodoc
comments ... */
+
+
/*! @endmodule Parser
+
*! @endmodule XML */
+
</
pre
><
p><
/
p
>
+
<
p
>
while the same example, ending in
<
/p><p></p><pre>
+
/*! @endmodule
+
*! @endmodule */
+
</pre><p></p>
+
<p>would be considered legal
.
</p
>
<p><pre>
+
Keyword: @class
+
Legal for: C files only (neither needed nor legal for Pike files)
+
Arguments: (the last segment of) the class name (ie no "
.
" allowed)
+
</pre></p><p>Example: to document the Process
.
create_process
class, you would use:
</
p
><
p><
/
p
>
<pre>
+
/*! @module Process
+
*! @class create_process */
+
<
/pre
><
p></p>
+
<p>And
end the scope similar to @module:</p><p></p><pre>
+
/*! @endclass create
_
process
+
*! @endmodule Process */
+
</pre
>
<p></p>
+
<p>Like @module tags, @class tags may be nested any number of levels
+
(when documenting subclasses to subclasses to subclasses to
..
.).</p><p><pre>
+
Keyword:
@endclass
+
Legal for: C files only (neither needed nor legal for
Pike
files)
+
Arguments:
(the last segment of) the class name (optional)
+
</
pre
></
p
>
<p>When the optional argument to @endclass is given (for code clarity),
+
the extractor will verify that the class scope you close was indeed
+
the one you opened, just as with @endmodule above.
<
/p
><
p><pre>
+
Keyword: @decl
+
Legal for: All source code (C and Pike files)
+
Arguments: (the last segment of) the identifier name (ie "." illegal)
+
</pre></p><p>The @decl keyword is used to target
a
specific (...more to come! :-)</p><p><pre>
+
+
+
+
+--------------------------------------+
+
| Pike autodoc markup - the XML format |
+
+--------------------------------------+
+
+
=
=====================================================================
+
a) Introduction
+
----------------------------------------------------------------------
+
+
When a piece of documentation is viewed in human-readable format, it
+
has gone through the following states:
+
+
1
.
Doc written in comments in source code (C or Pike).
+
+
2. A lot of smaller XML files, one for each source code file.
+
+
3.
A big chunk of XML, describing the whole hierarchy.
+
+
4. A repository of smaller and more manageable XML files.
+
+
5. A HTML page rendered from one such file.
+
(Or a PDF file, or whatever).
+
+
The transition from state 1 to state 2 is the extraction of
+
documentation from source files. There are several (well, at
+
least two) markup formats, and there are occasions where it is
+
handy to generate documentation automatically &c. This document
+
describes how a file in state 2 should be structured in order to
+
be handled correctly by subsequent passes and presented in a
+
consistent manner.
+
+
======================================================================
+
b) Overall structure
+
----------------------------------------------------------------------
+
+
Each source file adds some number of entities to the whole hierarchy.
+
It can contain a class or a module. It can contain an empty module,
+
that has its methods and members defined in some other source file,
+
and so on. Suppose we have a file containing documentation for the
+
class Class in the module Module. The XML skeleton of the file
+
would then be:
+
+
<module name="">
+
<module name="Module">
+
<class name="Class">
+
... perhaps some info on inherits, members &c ...
+
<doc>
+
... the documentation of the class Module.Class ...
+
</doc>
+
</class>
+
</module>
+
</module>
+
+
The <module name=""> refers to the top module. That element, and its
+
child <module name="Module">, exist only to put the <class name="Class">
+
in its correct position in the hierarchy. So we can divide the elements
+
in the XML file into two groups: skeletal elements and content elements.
+
+
Each actual module/class/whatever in the Pike hierarchy maps to at most
+
one content element, however it can map to any number of skeletal elements.
+
For example, the top module is mapped to a skeletal element in each XML
+
file extracted from a single source file. To get from state 2 to state
3
+
in the list above, all XML files are merged into one big
.
All the elements
+
that a module or class map to are merged into one, and if one of those
+
elements contains documentation (=is a content element), then that
+
documentation becomes a child of the merger of the elements.
+
+
======================================================================
+
c) Grouping
+
----------------------------------------------------------------------
+
+
Classes and modules always appear as <module> and <class> elements.
+
Methods, variables, constants &c, however, can be grouped in the
+
source code:
+
+
//! Two variables:
+
int a;
+
int b;
+
+
Even a single variable is considered as a group with one member.
+
Continuing the example in the previous section, suppose that Module.Class
+
has two member variables, a and b, that are documented as a group:
+
+
<module name="">
+
<module name="Module">
+
<class name="Class">
+
... perhaps some info on inherits, members &c ...
+
+
<docgroup homogen-type="variable">
+
<variable name="a"><type><int/></type></variable>
+
<variable name="b"><type><int/></type></variable>
+
<doc>
+
... documentation for Module.Class.a and Module.Class.b ...
+
</doc>
+
</docgroup>
+
+
<doc>
+
... the documentation of the class Module.Class ...
+
</doc>
+
</class>
+
</module>
+
</module>
+
+
If all the children of a <docgroup> are of the same type, e.g. all are
+
<method> elements, then the <docgroup> has the attribute homogen-type
+
(="method" in the example). If all the children have identical name="..."
+
attributes, then the <docgroup> gets a homogen-name="..." attribute aswell.
+
+
The <docgroup> has a <doc> child containing the docmentation for the other
+
children of the <docgroup>. An entity that cannot be grouped (class, module,
+
enum), has a <doc> child of its own instead.
+
+
======================================================================
+
d)
Pike
entities
+
----------------------------------------------------------------------
+
+
Pike
entities - classes, modules, methods, variables, constants, &c, have some
+
things in common, and many parts of the xml format are the same for all of
+
these entities. All entities are represented with an XML element, namely one
+
of:
+
+
<class>
+
<constant>
+
<enum>
+
<inherit>
+
<method>
+
<modifier>
+
<module>
+
<typedef>
+
<variable>
+
+
The names speak for themselves, except: <modifier> which is used for modifier
+
ranges:
+
+
/
/! Some variables:
+
static nomask {
+
int x, y;
+
+
string n;
+
}
+
+
A Pike entity may also have the following properties:
+
+
Name - Given as
a
name="..." attribute:
+
<variable name="i"> ... <
/
variable>
+
+
Modifiers - Given as
a
child element <modifiers>:
+
<variable name
=
"i">
+
<modifiers>
+
<optional/><static/><private/>
+
</modifiers>
+
.
..
+
</variable>
+
If there are no modifiers before the declaration of the entity, the
+
<modifiers> element can be omitted.
+
+
Source position - Given as a child element <source-position>:
+
<variable name="i">
+
<source-position file="/home/rolf/hejhopp.pike" first-line="12"/>
+
<modifiers>
+
<optional/><static/><private/>
+
</modifiers>
+
...
+
</variable>
+
The source position is the place in the code tree where the entity is
+
declared or defined. For a method, the attribute last-line="..." can be
+
added to <source-position> to give the range of lines that the method
+
body spans in the source code.
+
+
And then there are some things that are specific to each of the types of
+
entities:
+
+
<class>
+
All inherits of the class are given as child elements <inherit>. If there
+
is doc for the inherits, the <inherit> is repeated inside the appropriate
+
<docgroup>:
+
+
class Bosse {
+
inherit "arne.pike" : Arne;
+
inherit Benny;
+
+
//! Documented inherit
+
inherit Sven;
+
}
+
+
<class name="Bosse">
+
<inherit name="Arne"><source-position ... />
+
<classname>"arne.pike"</classname></inherit>
+
<inherit><source-position ... />
+
<classname>Benny</classname></inherit>
+
<inherit><source-position ... />
+
<classname>Sven</classname></inherit>
+
<docgroup homogen-type="inherit">
+
<doc>
+
<text><p>Documented inherit</p></text>
+
</doc>
+
<inherit><source-position ... />
+
<classname>Sven</classname></inherit>
+
</docgroup>
+
...
+
</class>
+
+
<constant>
+
Only has a name. The element is empty (or has a <source-position> child.)
+
+
<enum>
+
Works as a container. Has a <doc> child element with the documentation of
+
the enum itself, and <docgroup> elements with a <constant> for each enum
+
constant. So:
+
+
enum E
+
//! enum E
+
{
+
//! Three constants:
+
a, b, c,
+
+
//! One more:
+
d
+
}
+
+
becomes:
+
+
<enum name="E">
+
<doc><text><p>enum E</p></text></doc>
+
<docgroup homogen-type="constant">
+
<doc><text><p>Three constants:</p></text></doc>
+
<constant name="a"/>
+
<constant name="b"/>
+
<constant name="c"/>
+
</docgroup>
+
<docgroup homogen-name="d" homogen-type="constant">
+
<doc><text><p>One more:</p></text></doc>
+
<constant name="d"/>
+
</docgroup>
+
</enum>
+
+
Both the <enum> element and the <constant> elements could have
+
<source-position> children, of course.
+
+
<inherit>
+
The name="..." attribute gives the name after the colon, if any. The name
+
of the inherited class is given in a <classname> child. If a file name is
+
used, the class name is the file name surrounded by quotes (see <class>).
+
+
<method>
+
The arguments are given inside an <arguments> child. Each argument is
+
given as an <argument name="..."> element. Each <argument> has a <type>
+
child, with the type of the argument. The return type of the method is
+
given inside a <returntype> container:
+
+
int a(int x, int y);
+
+
<method name="a">
+
<arguments>
+
<argument name="x"><type><int/></type></argument>
+
<argument name="y"><type><int/></type></argument>
+
</arguments>
+
<returntype><int/></returntype>
+
</method>
+
+
<modifier>
+
Works as a container ... ???
+
+
<module>
+
Works just like <class>.
+
+
<typedef>
+
The type is given in a <type> child:
+
+
typedef float Boat;
+
+
<typedef name="Boat"><type><float/></type></typedef>
+
+
<variable>
+
The type of the variable is given in a <type> child:
+
+
int x;
+
+
<variable name="x"><type><int/></type></variable>
+
+
======================================================================
+
e) Pike types
+
----------------------------------------------------------------------
+
+
Above we have seen the types int and float represented as <int/> and <float/>.
+
Some of the types are complex, some are simple. The simpler types are just on
+
the form <foo/>:
+
+
<float/>
+
<mixed/>
+
<program/>
+
<string/>
+
<void/>
+
+
The same goes for mapping, array, function, object, multiset, &c that have
+
no narrowing type qualification: <mapping/>, <array/>, <function/> ...
+
+
The complex types are represented as follows:
+
+
array
+
If the type of the elements of the array is specified it is given in a
+
<valuetype> child element:
+
+
array(int)
+
+
<array><valuetype><int/></valuetype></array>
+
+
function
+
The types of the arguments and the return type are given (the order
+
of the <argtype> elements is significant, of course):
+
+
function(int, string: mixed)
+
+
<function>
+
<argtype><int/></argtype>
+
<argtype><string/></argtype>
+
<returntype><mixed/></returntype>
+
</function>
+
+
int
+
An int type can have a min and/or max value. The values can be numbers or
+
identifiers:
+
+
int(0..MAX)
+
+
<int><min>0</min><max>MAX</max></int>
+
+
mapping
+
The types of the indices and values are given:
+
+
mapping(int:int)
+
+
<mapping>
+
<indextype><int/></indextype>
+
<valuetype><int/></valuetype>
+
+
multiset
+
The type of the indices is given:
+
+
multiset(string)
+
+
<multiset>
+
<indextype><string/></indextype>
+
</multiset>
+
+
object
+
If the program/class is specified, it is given as the text child of
+
the <object> element:
+
+
object(Foo.Bar.Ippa)
+
+
<object>Foo.Bar.Ippa</object>
+
+
Then there are two special type constructions. A disjunct type is written
+
with the <or> element:
+
+
string|int
+
+
<or><string/><int/></or>
+
+
An argument to a method can be of the varargs type:
+
+
function(string, mixed ... : void)
+
+
<function>
+
<argtype><string/></argtype>
+
<argtype><varargs><mixed/></varargs></argtype>
+
<returntype><void/></returntype>
+
</function>
+
+
======================================================================
+
f) Other XML tags
+
----------------------------------------------------------------------
+
+
p
+
Paragraph.
+
+
i
+
Italic.
+
+
b
+
Bold.
+
+
tt
+
Terminal Type.
+
+
pre
+
Preformatted text.
+
+
code
+
Program code.
+
+
image
+
An image object. Contains the original file path to the image. Has the
+
optional attributes width, height and file, where file is the path to
+
the normalized-filename file.
+
+
======================================================================
+
g) XML generated from the doc markup
+
----------------------------------------------------------------------
+
+
The documentation for an entity is put in a <doc> element. The <doc> element
+
is either a child of the element representing the entity (in the case of
+
<class>, <module>, <enum>, or <modifiers>) or a child of the <docgroup> that
+
contains the element representing the entity.
+
+
The doc markup has two main types of keywords. Those that create a container
+
and those that create a new subsection within a container, implicitly closing
+
the previous subsection. Consider e.g.:
+
+
//! @mapping
+
//! @member int "ip"
+
//! The IP# of the host.
+
//! @member string "address"
+
//! The name of the host.
+
//! @member float "latitude"
+
//! @member float "longitude"
+
//! The coordinates of its physical location.
+
//! @endmapping
+
+
Here @mapping and @endmapping create a container, and each @member start a
+
new subsection. The two latter @member are grouped together and thus they
+
form ONE new subsection together. Each subsection is a <group>, and the
+
<group> has one or more <member> children, and a <text> child that contains
+
the text that describes the <member>s:
+
+
<mapping>
+
<group>
+
<member><type><int/></type><index>"ip"</index></member>
+
<text>
+
<p>The IP# of the host.</p>
+
</text>
+
</group>
+
<group>
+
<member><type><string/></type><index>"address"</index></member>
+
<text>
+
<p>The name of the host.</p>
+
</text>
+
</group>
+
<group>
+
<member><type><float/></type><index>"latitude"</index></member>
+
<member><type><float/></type><index>"longitude"</index></member>
+
<text>
+
<p>The coordinates of its physical location.</p>
+
</text>
+
</group>
+
</mapping>
+
+
Inside a <text> element, there can not only be text, but also a nested level
+
of, say @mapping - @endmapping. In that case, the <mapping> element is put in
+
the document order place as a sibling of the <p> that contain the text:
+
+
//! @mapping
+
//! @member mapping "nested-mapping"
+
//! A mapping inside the mapping:
+
//! @mapping
+
//! @member string "zip-code"
+
//! The zip code.
+
//! @endmapping
+
//! And some more text ...
+
//! @endmapping
+
+
becomes:
+
+
<mapping>
+
<group>
+
<member><type><mapping/></type><index>"nested-mapping"</index></member>
+
<text>
+
<p>A mapping inside the mapping:</p>
+
<mapping>
+
<group>
+
<member><type><string/></type><index>"zip-code"</index></member>
+
<text>
+
<p>The zip code.</p>
+
</text>
+
</group>
+
</mapping>
+
<p>And some more text ...</p>
+
</text>
+
</group>
+
</mapping>
+
+
Inside the <p> elements, there may also be some more "layout-ish" tags like
+
<b>, <code>, <tt>, <i>, needed to make the text more readable. Those tags are
+
expressed as @i{ ... @} in the doc markup. However there are no <br>. A
+
paragraph break is done by ending the <p> and beginning a new. A </p><p> is
+
inserted for each sequence of blank lines in the doc markup:
+
+
//! First paragraph.
+
//!
+
//! Second paragraph.
+
//!
+
//!
+
+
becomes:
+
+
<p>First paragraph.</p><p>Second paragraph.</p>
+
+
Note that the text is trimmed from leading and ending whitespaces, and there
+
are never any empty <p> elements.
+
+
In the example above the keyword `@mapping
'
translated into <mapping>, whereas
+
the keyword `@member string "zip-code"' translated into:
+
<member><type><string/></type><index>"zip-code"</index></member>
+
+
The translation of keyword->XML is done differently for each keyword
.
How it
+
is done can be seen in lib/modules/Tools.pmod/AutoDoc.pmod/DocParser.pmod. Most
+
keywords just interpret the arguments as a space-separated list, and put their
+
values in attributes to the element. In some cases (such as @member) though,
+
some more intricate parsing must be done, and the arguments may be complex
+
(like
Pike
types) and are represented as child elements of the element.
+
+
======================================================================
+
h) Top level sections of different Pike entities.
+
----------------------------------------------------------------------
+
+
In every doc comment there is an implicit "top container", and subsections can
+
be opened in it. E.g.:
+
+
/
/! A method.
+
//! @param x
+
//! The horizontal coordinate.
+
//! @param y
+
//! The vertical coordinate.
+
//! @returns
+
//! Nothing :)
+
void foo(int x, int y)
+
+
becomes:
+
+
<docgroup homogen-name="foo" homogen-type="method">
+
<doc>
+
<text><p>A method.</p></text>
+
<group>
+
<param name="x"/>
+
<text><p>The horizontal coordinate.</p></text>
+
</group>
+
<group>
+
<param name="y"/>
+
<text><p>The vertical coordinate.</p></text>
+
</group>
+
<group>
+
<returns/>
+
<text><p>Nothing :)</p></text>
+
</group>
+
</doc>
+
<method name="foo">
+
......
+
</method>
+
</docgroup>
+
+
Which "top container" subsections are allowed depends on what type of entity is
+
documented:
+
+
ALL - <bugs/>
+
<deprecated> ... </deprecated>
+
<example/>
+
<note/>
+
<seealso/>
+
+
<method> - <param name="..."/>
+
<returns/>
+
<throws/>
+
</
pre
></
p
></dd></dl></body></html>