1Documenting public Functions and Macros
2=======================================
3
4In the last few years, the OpenSSL project has strived to improve the quality
5and coverage of the API documentation. A while ago, this goal has been
6turned into an official [documentation-policy]. This policy is actively
7enforced by the `make doc-nits` target resp. `check-docs` GitHub action.
8
9[documentation-policy]: https://www.openssl.org/policies/technical/documentation-policy.html
10
11If you add a new public function or macro to a header file without documenting
12it, it will give you an error message like this:
13
14```text
15include/openssl/bio.h: macro BIO_set_dgram_origin(3) undocumented
16include/openssl/bio.h: macro BIO_get_dgram_origin(3) undocumented
17include/openssl/bio.h: macro BIO_set_dgram_dest(3) undocumented
18include/openssl/bio.h: macro BIO_get_dgram_dest(3) undocumented
19```
20
21and you'll want to document this.
22
23So, create a new `.pod` file named `doc/man3/FUNCTION.pod`.
24
25If you are asked to document several related functions in that file,
26you can create a single pod file in which you document them together.
27In this case, use the name of the first function as the file name,
28like for the above example:
29
30```text
31doc/man3/BIO_set_dgram_origin.pod
32```
33
34If you do use an unrelated name (like `BIO_dgram.pod`) then you'll get
35a warning about that.
36
37Next, you need to add your new file to the `doc/build.info` file.
38This command does it automatically for you:
39
40```console
41$ make generate_doc_buildinfo
42```
43
44this will update `doc/build.info`.
45You should git add the result as `generate_doc_buildinfo` is not run on every build.
46
47With these two changes, running `make doc-nits` locally should
48now agree with you that you have documented all your new defines,
49but it might then complain:
50
51```text
52BIO_get_dgram_dest(3) is supposedly internal
53(maybe missing from other.syms) but is documented as public
54```
55
56If it is the case that your interface is meant to be public, then you need
57to edit the file `util/other.syms` to add the names of your `#define`
58functions.
59This file gets sorted alphabetically prior to each major release,
60but new additions should be placed at the end of the file.
61
62Example
63-------
64
65For demonstration purposes, two new public symbols have been added
66by "implementing" a public function `BIO_set_dgram_foo()`
67and a public function-like macro `BIO_set_dgram_bar()`:
68
69```diff
70diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
71index 82d382cf4e..30382f0abe 100644
72--- a/crypto/bio/bss_dgram.c
73+++ b/crypto/bio/bss_dgram.c
74@@ -192,6 +192,13 @@ BIO *BIO_new_dgram(int fd, int close_flag)
75     return ret;
76 }
77
78+
79+int BIO_set_dgram_foo(BIO* b, int foo)
80+{
81+    return foo;
82+}
83+
84+
85 static int dgram_new(BIO *bi)
86 {
87     bio_dgram_data *data = OPENSSL_zalloc(sizeof(*data));
88diff --git a/include/openssl/bio.h.in b/include/openssl/bio.h.in
89index c70185db34..4ddea2f96b 100644
90--- a/include/openssl/bio.h.in
91+++ b/include/openssl/bio.h.in
92@@ -485,6 +485,9 @@ struct bio_dgram_sctp_prinfo {
93 #define BIO_set_dgram_dest(b, addr)   BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, addr)
94 #define BIO_get_dgram_dest(b, addr)   BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, addr)
95
96+int BIO_set_dgram_foo(BIO* b, int foo);
97+#define BIO_set_dgram_bar(b, bar) BIO_ctrl(b, BIO_CTRL_DGRAM_SET_ADDR, 0, bar)
98+
99 /*
100  * name is cast to lose const, but might be better to route through a
101  * function so we can do it safely
102```
103
104If you run `make doc-nits`, you might be surprised that it only
105complains about the undocumented macro, not the function:
106
107```console
108$ make doc-nits
109
110/usr/bin/perl ./util/find-doc-nits -c -n -l -e
111include/openssl/bio.h: macro BIO_set_dgram_bar(3) undocumented
112# 1 macros undocumented (count is approximate)
113make: *** [Makefile:3833: doc-nits] Error 1
114```
115
116The explanation for this is that one important step is still missing,
117it needs to be done first: you need to run
118
119```console
120$ make update
121```
122
123which triggers a scan of the public headers for new API functions.
124
125All new functions will be added to either `util/libcrypto.num`
126or `util/libssl.num`.
127Those files store the information about the symbols which need
128to be exported from the shared library resp. DLL.
129Among other stuff, they contain the ordinal numbers for the
130[module definition file] of the Windows DLL, which is the
131reason for the `.num` extension.
132
133[module definition file]: https://docs.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-def-files
134
135After running `make update`, you can use `git diff` to check the outcome:
136
137```diff
138diff --git a/util/libcrypto.num b/util/libcrypto.num
139index 394f454732..fc3c67313a 100644
140--- a/util/libcrypto.num
141+++ b/util/libcrypto.num
142@@ -5437,3 +5437,4 @@ BN_signed_bn2native                     ? 3_1_0   EXIST::FUNCTION:
143 ASYNC_set_mem_functions                 ?  3_1_0   EXIST::FUNCTION:
144 ASYNC_get_mem_functions                 ?  3_1_0   EXIST::FUNCTION:
145 BIO_ADDR_dup                            ?  3_1_0   EXIST::FUNCTION:SOCK
146+BIO_set_dgram_foo                       ?  3_1_0   EXIST::FUNCTION:
147```
148
149The changes need to be committed, ideally as a separate commit:
150
151```console
152$ git commit -a -m "make update"
153```
154
155which has the advantage that it can easily be discarded when it
156becomes necessary to rerun `make update`.
157
158Finally, we reached the point where `make doc-nits` complains about
159both symbols:
160
161```console
162$ make doc-nits
163/usr/bin/perl ./util/find-doc-nits -c -n -l -e
164crypto: function BIO_set_dgram_foo(3) undocumented
165# 1 libcrypto names are not documented
166include/openssl/bio.h: macro BIO_set_dgram_bar(3) undocumented
167# 1 macros undocumented (count is approximate)
168make: *** [Makefile:3833: doc-nits] Error 1
169```
170
171Summary
172-------
173
174The bottom line is that only the way how the public symbols
175are recorded is different between functions and macros,
176the rest of the documentation procedure is analogous.
177