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 171Additionally, public symbols added should contain an entry in the HISTORY 172section of their documentation explaining the exact OpenSSL version in which 173they have appeared for the first time. The option -i for "find-doc-nits" 174can be utilized to check for this. A completely new documentation file 175should also contain a HISTORY section with wording along this line, e.g. 176"These functions have been added in OpenSSL version xxx.". 177 178Summary 179------- 180 181The bottom line is that only the way how the public symbols 182are recorded is different between functions and macros, 183the rest of the documentation procedure is analogous. 184