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