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