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