1 Documenting public Functions and Macros 2 ======================================= 3 4 In the last few years, the OpenSSL project has strived to improve the quality 5 and coverage of the API documentation. A while ago, this goal has been 6 turned into an official [documentation-policy]. This policy is actively 7 enforced 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 11 If you add a new public function or macro to a header file without documenting 12 it, it will give you an error message like this: 13 14 ```text 15 include/openssl/bio.h: macro BIO_set_dgram_origin(3) undocumented 16 include/openssl/bio.h: macro BIO_get_dgram_origin(3) undocumented 17 include/openssl/bio.h: macro BIO_set_dgram_dest(3) undocumented 18 include/openssl/bio.h: macro BIO_get_dgram_dest(3) undocumented 19 ``` 20 21 and you'll want to document this. 22 23 So, create a new `.pod` file named `doc/man3/FUNCTION.pod`. 24 25 If you are asked to document several related functions in that file, 26 you can create a single pod file in which you document them together. 27 In this case, use the name of the first function as the file name, 28 like for the above example: 29 30 ```text 31 doc/man3/BIO_set_dgram_origin.pod 32 ``` 33 34 If you do use an unrelated name (like `BIO_dgram.pod`) then you'll get 35 a warning about that. 36 37 Next, you need to add your new file to the `doc/build.info` file. 38 This command does it automatically for you: 39 40 ```console 41 $ make generate_doc_buildinfo 42 ``` 43 44 this will update `doc/build.info`. 45 You should git add the result as `generate_doc_buildinfo` is not run on every build. 46 47 With these two changes, running `make doc-nits` locally should 48 now agree with you that you have documented all your new defines, 49 but it might then complain: 50 51 ```text 52 BIO_get_dgram_dest(3) is supposedly internal 53 (maybe missing from other.syms) but is documented as public 54 ``` 55 56 If it is the case that your interface is meant to be public, then you need 57 to edit the file `util/other.syms` to add the names of your `#define` 58 functions. 59 This file gets sorted alphabetically prior to each major release, 60 but new additions should be placed at the end of the file. 61 62 Example 63 ------- 64 65 For demonstration purposes, two new public symbols have been added 66 by "implementing" a public function `BIO_set_dgram_foo()` 67 and a public function-like macro `BIO_set_dgram_bar()`: 68 69 ```diff 70 diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c 71 index 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)); 88 diff --git a/include/openssl/bio.h.in b/include/openssl/bio.h.in 89 index 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 104 If you run `make doc-nits`, you might be surprised that it only 105 complains 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 111 include/openssl/bio.h: macro BIO_set_dgram_bar(3) undocumented 112 # 1 macros undocumented (count is approximate) 113 make: *** [Makefile:3833: doc-nits] Error 1 114 ``` 115 116 The explanation for this is that one important step is still missing, 117 it needs to be done first: you need to run 118 119 ```console 120 $ make update 121 ``` 122 123 which triggers a scan of the public headers for new API functions. 124 125 All new functions will be added to either `util/libcrypto.num` 126 or `util/libssl.num`. 127 Those files store the information about the symbols which need 128 to be exported from the shared library resp. DLL. 129 Among other stuff, they contain the ordinal numbers for the 130 [module definition file] of the Windows DLL, which is the 131 reason 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 135 After running `make update`, you can use `git diff` to check the outcome: 136 137 ```diff 138 diff --git a/util/libcrypto.num b/util/libcrypto.num 139 index 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 149 The changes need to be committed, ideally as a separate commit: 150 151 ```console 152 $ git commit -a -m "make update" 153 ``` 154 155 which has the advantage that it can easily be discarded when it 156 becomes necessary to rerun `make update`. 157 158 Finally, we reached the point where `make doc-nits` complains about 159 both symbols: 160 161 ```console 162 $ make doc-nits 163 /usr/bin/perl ./util/find-doc-nits -c -n -l -e 164 crypto: function BIO_set_dgram_foo(3) undocumented 165 # 1 libcrypto names are not documented 166 include/openssl/bio.h: macro BIO_set_dgram_bar(3) undocumented 167 # 1 macros undocumented (count is approximate) 168 make: *** [Makefile:3833: doc-nits] Error 1 169 ``` 170 171 Additionally, public symbols added should contain an entry in the HISTORY 172 section of their documentation explaining the exact OpenSSL version in which 173 they have appeared for the first time. The option -i for "find-doc-nits" 174 can be utilized to check for this. A completely new documentation file 175 should also contain a HISTORY section with wording along this line, e.g. 176 "These functions have been added in OpenSSL version xxx.". 177 178 Summary 179 ------- 180 181 The bottom line is that only the way how the public symbols 182 are recorded is different between functions and macros, 183 the rest of the documentation procedure is analogous. 184