Home | History | Annotate | Line # | Download | only in HOWTO
      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