]> git.ipfire.org Git - thirdparty/squid.git/blob - doc/Programming-Guide/02_CodingConventions.dox
Source Format Enforcement (#532)
[thirdparty/squid.git] / doc / Programming-Guide / 02_CodingConventions.dox
1 /*
2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 /**
10 \page Conventions Coding and Other Conventions used in Squid
11
12 \section Coding Code Conventions
13 \par
14 Most custom types and tools are documented in the code or the relevant
15 portions of this manual. Some key points apply globally however.
16
17 \section FWT Fixed Width types
18
19 \par
20 If you need to use specific width types - such as
21 a 16 bit unsigned integer, use one of the following types. To access
22 them simply include "squid.h".
23
24 \verbatim
25 int16_t - 16 bit signed.
26 uint16_t - 16 bit unsigned.
27 int32_t - 32 bit signed.
28 uint32_t - 32 bit unsigned.
29 int64_t - 64 bit signed.
30 uint64_t - 64 bit unsigned.
31 \endverbatim
32
33 \section Documentation Documentation Conventions
34 \par
35 Now that documentation is generated automatically from the sources
36 some common comment conventions need to be adopted.
37
38
39 \subsection CommentComponents API vs Internal Component Commenting
40
41 \par
42 First among these is a definition separation between component API
43 and Internal operations. API functions and objects should always be
44 commented and in the *.h file for the component. Internal logic and
45 objects should be commented in the *.cc file where they are defined.
46 The group is to be defined in the components main files with the
47 overview paragraphs about the API usage or component structure.
48
49 \par
50 With C++ classes it is easy to separate API and Internals with the C++
51 public: and private: distinctions on whichever class defines the
52 component API. An Internal group may not be required if there are no
53 additional items in the Internals (rare as globals are common in squid).
54
55 \par
56 With unconverted modules still coded in Objective-C, the task is harder.
57 In these cases two sub-groups must be defined *API and *Internal into
58 which naturally individual functions, variables, etc. are grouped using
59 the \b \\ingroup tag. The API group is usually a sub-group of Components
60 and the Internal is always a sub-group of the API.
61
62 \par Rule of thumb:
63 For both items, if its referenced from elsewhere in the code or
64 defined in the .h file it should be part of the API.
65 Everything else should be in the Internals group and kept out of the .h file.
66
67 \subsection FunctionComments Function/Method Comments
68
69 \par
70 All descriptions may be more than one line, and while whitespace formatting is
71 ignored by doxygen, it is good to keep it clear for manual reading of the code.
72
73 \par
74 Any text directly following a \b \\par tag will be highlighted in bold
75 automatically (like all the 'For Examples' below) so be careful what is placed
76 there.
77
78
79 \subsubsection PARAM Function Parameters
80
81 \par
82 Function and Method parameters MUST be named in both the definition and in
83 the declaration, and they also MUST be the same text. The doxygen parser
84 needs them to be identical to accurately link the two with documentation.
85 Particularly linking function with documentation of the label itself.
86
87 \par
88 Each function that takes parameters should have the possible range of values
89 commented in the pre-function descriptor. For API function this is as usual
90 in the .h file, for Internal functions it is i the .(cc|cci) file.
91
92 \par
93 The \b \\param tag is used to describe these. It takes two required parameters;
94 the name of the function parameter being documented followed immediately by
95 either [in], [out], or [in,out].
96 Followed by an optional description of what the parameter represents.
97
98 \par For Example:
99 \verbatim
100 /**
101 \param g[out] Buffer to receive something
102 \param glen[in] Length of buffer available to write
103 */
104 void
105 X::getFubar(char *g, int glen)
106 ...
107 \endverbatim
108
109
110 \subsubsection RETVAL Return Values
111
112 \par
113 Each function that returns a value should have the possible range of values
114 commented in the pre-function descriptor.
115 \par
116 The \b \\retval tag is used to describe these. It takes one required parameter;
117 the value or range of values returned.
118 Followed by an optional description of what/why of that value.
119
120 \par For Example:
121 \verbatim
122 /**
123 \retval 0 when FUBAR does not start with 'F'
124 \retval 1 when FUBAR starts with F
125 */
126 int
127 X::saidFubar()
128 ...
129 \endverbatim
130
131 \par Alternatively
132 when a state or other context-dependent object is returned the \b \\return
133 tag is used. It is followed by a description of the object and ideally its
134 content.
135
136
137 \subsubsection FLOW Function Actions / Internal Flows
138
139 \par Simple functions
140 do not exactly need a detailed description of their operation.
141 The \ref PARAM and \ref RETVAL
142 should be enough for any developer to understand the function.
143
144 \par Long or Complex Functions
145 do however need some commenting.
146 A well-designed function does all its operations in distinct blocks;
147 \arg Input validation
148 \arg Processing on some state
149 \arg Processing on the output of that earlier processing
150 \arg etc, etc.
151
152 \par
153 Each of these design blocks inside the function should be given a comment
154 indicating what they do. The comments should begin with
155 \verbatim /** \\par \endverbatim
156 The resulting function description will then contain a paragraph on each of the
157 blocks in the order they occur in the function.
158
159 \par For example:
160 \verbatim
161 /**
162 \param g The buffer to be used
163 \param glen Length of buffer provided
164 \param state Object of type X storing foo
165 */
166 void
167 fubar(char *g, int glen, void *state) {
168 \endverbatim
169 Designed validation part of the function
170 \verbatim
171 /** \par
172 * When g is NULL or gen is 0 nothing is done */
173 if(g == NULL || glen < 1)
174 return;
175
176 /** \par
177 * When glen is longer than the accepted length it gets truncated */
178 if(glen > MAX_FOO) glen = MAX_FOO;
179 \endverbatim
180 now we get on to the active part of the function
181 \verbatim
182 /** \par
183 * Appends up to MAX_FOO bytes from g onto the end of state->foo
184 * then passes the state off to FUBAR.
185 * No check for null-termination is done.
186 */
187 memcpy(g, glen, state->foo_end_ptr );
188 state->foo_end_ptr += glen;
189 fubar(state);
190 }
191 \endverbatim
192
193 \par
194 Of course, this is a very simple example. This type of comment should only be
195 needed in the larger functions with many side effects.
196 A function this small could reasonably have all its commenting done just ahead of
197 the parameter description.
198
199 */