1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
11
  
12
  
13
  
14
  
15
  
16
  
17
  
18
  
19
  
20
  
21
  
22
  
23
  
24
  
25
  
26
  
27
  
28
  
29
  
30
  
31
  
32
  
33
  
34
  
35
  
36
  
37
  
38
  
39
  
40
  
41
  
42
  
43
  
44
  
45
  
46
  
47
  
48
  
49
  
50
  
51
  
52
  
53
  
54
  
55
  
56
  
57
  
58
  
59
  
60
  
61
  
62
  
63
  
64
  
65
  
66
  
67
  
68
  
69
  
70
  
71
  
72
  
73
  
74
  
75
  
76
  
77
  
78
  
79
  
80
  
81
  
82
  
83
  
84
  
85
  
86
  
87
  
88
  
89
  
90
  
91
  
92
  
93
  
94
  
95
  
96
  
97
  
98
  
99
  
100
  
101
  
102
  
103
  
104
  
105
  
106
  
107
  
108
  
109
  
110
  
111
  
112
  
113
  
114
  
115
  
116
  
117
  
118
  
119
  
120
  
121
  
122
  
123
  
124
  
125
  
126
  
127
  
128
  
129
  
130
  
131
  
132
  
133
  
134
  
135
  
136
  
137
  
138
  
139
  
140
  
141
  
142
  
143
  
144
  
145
  
146
  
147
  
148
  
149
  
150
  
151
  
152
  
153
  
154
  
155
  
156
  
157
  
158
  
159
  
160
  
161
  
162
  
163
  
164
  
165
  
166
  
167
  
168
  
169
  
170
  
171
  
172
  
173
  
174
  
175
  
176
  
177
  
178
  
179
  
180
  
181
  
182
  
183
  
184
  
185
  
186
  
187
  
188
  
189
  
190
  
191
  
192
  
193
  
194
  
195
  
196
  
197
  
198
  
199
  
200
  
201
  
202
  
203
  
204
  
205
  
206
  
207
  
208
  
209
  
210
  
211
  
212
  
213
  
214
  
215
  
216
  
217
  
218
  
219
  
220
  
221
  
222
  
223
  
                      +-----------------------+ 
                      | Pike autodoc inlining | 
                      +-----------------------+ 
 
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. 
 
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. 
 
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. 
 
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. 
 
====================================================================== 
a) C files 
---------------------------------------------------------------------- 
 
In C files, the doc comments look like: 
 
  /*! yadda yadda 
   *! yadda yadda yadda 
   */ 
 
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. 
 
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. 
 
  /*! @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 */ 
 
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. 
 
 
====================================================================== 
b) Pike files 
---------------------------------------------------------------------- 
 
Doc comments look like: 
 
  //! yadda yadda yadda 
  //! yadda yadda 
 
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: 
 
  //! 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; } 
 
 
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: 
 
//! Doc for the class 
class CheeseMaker 
{ 
  //! You can even document inherits! 
  inherit Earth : earth; 
 
  //! Doc for CheeseMaker->a() 
  int a() 
  { 
    ... 
  } 
 
  void create(string s) { ... } 
} 
 
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: 
 
class a() 
{ 
  //! @decl foo 
  //!    ... doc for foo ... 
} 
 
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: 
 
  //! @decl int a(int x) 
  //! @decl int b(int x) 
  //!   Here is some doc for these functions.... 
 
is autodocwise equivalent to: 
 
  //! Here is some doc for these functions.... 
  int a(int x) 
  { 
     ..... 
  } 
  int b(int x) 
  { 
     ..... 
  } 
 
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: 
 
  //! @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) 
  { 
     .... 
  } 
 
The real method prototype is discarded in favour to the @decl'ed 
variants, who will be shown in the documentation instead. 
 
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: 
 
  #ifdef MALE 
    int bertil() 
  #else 
    int berit() 
  #endif 
  { 
    ... body ... 
  }