From b7a4b52f73d51db6077d2c0b56be262c36f472f7 Mon Sep 17 00:00:00 2001 From: "E. Scott Daniels" Date: Thu, 7 Nov 2019 15:35:17 -0500 Subject: [PATCH] Add root level docs control files Several control files must exist at the repo root, not in docs, in order to vet and push the documentation out to some remote site. This changes adds those files, and fixes the formatting issues that RST vetting is complaining about. Signed-off-by: E. Scott Daniels Change-Id: Ibeda532f0524d5f5d4d138ece4e9265429fa322b --- .readthedocs.yaml | 42 ++++++++++ README | 14 ++++ doc/src/generic_ps.im | 2 + doc/src/man/rmr_bytes2payload.3.xfm | 4 +- doc/src/man/rmr_get_meid.3.xfm | 12 +-- doc/src/man/rmr_get_srcip.3.xfm | 2 +- doc/src/man/rmr_get_xact.3.xfm | 12 +-- doc/src/man/rmr_init.3.xfm | 4 +- doc/src/man/rmr_init_trace.3.xfm | 2 +- doc/src/man/rmr_mt_call.3.xfm | 8 +- doc/src/man/rmr_mt_rcv.3.xfm | 2 +- doc/src/man/rmr_send_msg.3.xfm | 2 +- doc/src/man/rmr_set_stimeout.3.xfm | 26 +++--- doc/src/man/rmr_str2meid.3.xfm | 2 +- doc/src/man/rmr_str2xact.3.xfm | 2 +- doc/src/markdown.im | 1 + doc/src/roff.im | 2 + doc/src/rst.im | 1 + doc/src/rtd/Makefile | 1 - doc/src/rtd/README | 8 ++ doc/src/rtd/developer-guide.xfm | 2 +- doc/src/txt.im | 2 + docs/_static/logo.png | Bin 0 -> 10661 bytes docs/developer-guide.rst | 28 +++---- docs/index.rst | 3 + docs/release-notes.rst | 155 ------------------------------------ docs/user-guide.rst | 124 ++++++++++++++--------------- tox.ini | 54 +++++++++++++ 28 files changed, 245 insertions(+), 272 deletions(-) create mode 100644 .readthedocs.yaml create mode 100644 docs/_static/logo.png delete mode 100644 docs/release-notes.rst create mode 100644 tox.ini diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..44c62b3 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,42 @@ +# vim: ts=4 expandtab sw=4: +#================================================================================== +# Copyright (c) 2019 Nokia +# Copyright (c) 2018-2019 AT&T Intellectual Property. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#================================================================================== + +# NOTE: this exists only to support the RTD scraper(s). Future: change requirements +# so this can be moved inside of docs/ rather than polluting the top level. + +--- +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details +# Required +version: 2 + +formats: + - htmlzip + +build: + image: latest + +python: + version: 3.7 + install: + - requirements: docs/requirements-docs.txt + +sphinx: + configuration: docs/conf.py + diff --git a/README b/README index f3772d4..0f283f6 100644 --- a/README +++ b/README @@ -58,3 +58,17 @@ src This directory is the top level source directory containing both the test All unit and application level tests for the core library are kept within this directory. Tests for bindings are managed within the binding's directory under the source directory. + +Top level pollution +There are several "configuration" files which sit at the top level of the +repo that are required for some sort of CI/CD/Documentation automation. Most, +if not all of the CI/CD goo is in the ci directory where it's out of the way +and thus not confusing. However, there is some pollution that can generally +be ignored: + + tox.ini -- this seems to drive the scraper which pulls from docs and + writes to some external documentation repo/host. + + + .readthedocs.yaml -- this seems to be some configuration for the docs + scraping process(es). diff --git a/doc/src/generic_ps.im b/doc/src/generic_ps.im index f300c05..9020b91 100644 --- a/doc/src/generic_ps.im +++ b/doc/src/generic_ps.im @@ -20,6 +20,8 @@ .** macros compatable with the roff/troff and rts imbed files .** this is included when generating postscript from the man source. + .dv esc : .** rst needs an escape for some things + .hn off .dv text_size 10p .dv ex_size 8p diff --git a/doc/src/man/rmr_bytes2payload.3.xfm b/doc/src/man/rmr_bytes2payload.3.xfm index 74bc4fc..9deeef4 100644 --- a/doc/src/man/rmr_bytes2payload.3.xfm +++ b/doc/src/man/rmr_bytes2payload.3.xfm @@ -46,9 +46,9 @@ void rmr_bytes2payload( rmr_mbuf_t* mbuf, unsigned char* src, int len ) &h2(DESCRIPTION) This is a convenience function as some wrapper languages might not have the ability to directly copy into the payload buffer. -The bytes from &ital( src ) for the length given are copied to the payload. +The bytes from &ital(src) for the length given are copied to the payload. It is the caller's responsibility to ensure that the payload is large enough. -Upon successfully copy, the &cw( len ) field in the message buffer is updated to +Upon successfully copy, the &cw(len) field in the message buffer is updated to reflect the number of bytes copied. .sp There is little error checking, and no error reporting. diff --git a/doc/src/man/rmr_get_meid.3.xfm b/doc/src/man/rmr_get_meid.3.xfm index 3980542..d31bb3c 100644 --- a/doc/src/man/rmr_get_meid.3.xfm +++ b/doc/src/man/rmr_get_meid.3.xfm @@ -46,18 +46,18 @@ char* rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest ) &h2(DESCRIPTION) The &cw(rmr_get_meid) function will copy the managed equipment ID (meid) field from the message into the &ital(dest) buffer provided by the user. -The buffer referenced by &ital( dest ) is assumed to be at least &cw(RMR_MAX_MEID) bytes in length. -If &ital( dest ) is NULL, then a buffer is allocated (the calling application is expected +The buffer referenced by &ital(dest) is assumed to be at least &cw(RMR_MAX_MEID) bytes in length. +If &ital(dest) is NULL, then a buffer is allocated (the calling application is expected to free when the buffer is no longer needed). &h2(RETURN VALUE) On success, a pointer to the extracted string is returned. -If &ital( dest ) was supplied, then this is just a pointer to the caller's buffer. -If &ital( dest ) was NULL, this is a pointer to the allocated buffer. +If &ital(dest) was supplied, then this is just a pointer to the caller's buffer. +If &ital(dest) was NULL, this is a pointer to the allocated buffer. If an error occurs, a nil pointer is returned and errno is set as described below. &h2(ERRORS) -If an error occurs, the value of the global variable &cw( errno ) will be set to one of +If an error occurs, the value of the global variable &cw(errno) will be set to one of the following with the indicated meaning. &beg_dlist(.75i : ^&bold_font ) @@ -65,7 +65,7 @@ the following with the indicated meaning. &di(EINVAL) The message, or an internal portion of the message, was corrupted or the pointer was invalid. &half_space -&di(ENOMEM) A nil pointer was passed for &ital( dest, ) however it was not possible to allocate a +&di(ENOMEM) A nil pointer was passed for &ital(dest,) however it was not possible to allocate a buffer using malloc(). &end_dlist diff --git a/doc/src/man/rmr_get_srcip.3.xfm b/doc/src/man/rmr_get_srcip.3.xfm index 489d1e5..9e3103b 100644 --- a/doc/src/man/rmr_get_srcip.3.xfm +++ b/doc/src/man/rmr_get_srcip.3.xfm @@ -62,7 +62,7 @@ On success, a pointer to the destination buffer is given as a convenience to the On failure, a nil pointer is returned and the value of errno is set. &h2(ERRORS) -If an error occurs, the value of the global variable &cw( errno ) will be set to one of +If an error occurs, the value of the global variable &cw(errno) will be set to one of the following with the indicated meaning. &beg_dlist(.75i : ^&bold_font ) diff --git a/doc/src/man/rmr_get_xact.3.xfm b/doc/src/man/rmr_get_xact.3.xfm index 8674702..6506614 100644 --- a/doc/src/man/rmr_get_xact.3.xfm +++ b/doc/src/man/rmr_get_xact.3.xfm @@ -46,18 +46,18 @@ char* rmr_get_xact( rmr_mbuf_t* mbuf, unsigned char* dest ) &h2(DESCRIPTION) The &cw(rmr_get_xact) function will copy the transaction field from the message into the &ital(dest) buffer provided by the user. -The buffer referenced by &ital( dest ) is assumed to be at least &cw(RMR_MAX_XID) bytes in length. -If &ital( dest ) is NULL, then a buffer is allocated (the calling application is expected +The buffer referenced by &ital(dest) is assumed to be at least &cw(RMR_MAX_XID) bytes in length. +If &ital(dest) is NULL, then a buffer is allocated (the calling application is expected to free when the buffer is no longer needed). &h2(RETURN VALUE) On success, a pointer to the extracted string is returned. -If &ital( dest ) was supplied, then this is just a pointer to the caller's buffer. -If &ital( dest ) was NULL, this is a pointer to the allocated buffer. +If &ital(dest) was supplied, then this is just a pointer to the caller's buffer. +If &ital(dest) was NULL, this is a pointer to the allocated buffer. If an error occurs, a nil pointer is returned and errno is set as described below. &h2(ERRORS) -If an error occurs, the value of the global variable &cw( errno ) will be set to one of +If an error occurs, the value of the global variable &cw(errno) will be set to one of the following with the indicated meaning. &beg_dlist(.75i : ^&bold_font ) @@ -65,7 +65,7 @@ the following with the indicated meaning. &di(EINVAL) The message, or an internal portion of the message, was corrupted or the pointer was invalid. &half_space -&di(ENOMEM) A nil pointer was passed for &ital( dest, ) however it was not possible to allocate a +&di(ENOMEM) A nil pointer was passed for &ital(dest,) however it was not possible to allocate a buffer using malloc(). &end_dlist diff --git a/doc/src/man/rmr_init.3.xfm b/doc/src/man/rmr_init.3.xfm index 488e6d2..5413beb 100644 --- a/doc/src/man/rmr_init.3.xfm +++ b/doc/src/man/rmr_init.3.xfm @@ -57,7 +57,7 @@ a specific message. &space &ital(Flags) allows for selection of some RMr options at the time of initialisation. -These are set by ORing &cw(RMRFL_) constants from the RMr header file. Currently the +These are set by ORing &cw(RMRFL) constants from the RMr header file. Currently the following flags are supported: &half_space @@ -83,7 +83,7 @@ Further, timeouts were message count based and not time unit based. Multi-threaded call support adds the ability for a user application with multiple threads to invoke a blocking call function with the guarentee that the correct response message is delivered to the thread. -The additional support is implemented with the &ital( rmr_mt_call() ) and &ital( rmr_mt_rcv() ) +The additional support is implemented with the &ital(rmr_mt_call()) and &ital(rmr_mt_rcv()) function calls. &space diff --git a/doc/src/man/rmr_init_trace.3.xfm b/doc/src/man/rmr_init_trace.3.xfm index f31baf0..9168c68 100644 --- a/doc/src/man/rmr_init_trace.3.xfm +++ b/doc/src/man/rmr_init_trace.3.xfm @@ -66,7 +66,7 @@ a message later, the &cw(rmr_tralloc_msg()) function can be used. &h2(RETURN VALUE) A value of 1 is returned on success, and 0 on failure. A failure indicates that the -RMr context (void *) passed to this function was not valid. +RMr context (a void pointer passed to this function was not valid. &h2(SEE ALSO ) .ju off diff --git a/doc/src/man/rmr_mt_call.3.xfm b/doc/src/man/rmr_mt_call.3.xfm index 76d209f..6ba797d 100644 --- a/doc/src/man/rmr_mt_call.3.xfm +++ b/doc/src/man/rmr_mt_call.3.xfm @@ -50,12 +50,12 @@ control to the user application. The user application supplies a completed message buffer, as it would for a &cw(rmr_send_msg) call, but unlike with a send, the buffer returned will have the response from the application that received the message. -The thread invoking the &ital( rmr_mt_call()) will block until a message arrives +The thread invoking the &ital(rmr_mt_call()) will block until a message arrives or until &ital(timeout) milliseconds has passed; which ever comes first. Using a timeout value of zero (0) will cause the thread to block without a timeout. &space -The &ital( id ) supplied as the third parameter is an integer in the range of 2 through +The &ital(id) supplied as the third parameter is an integer in the range of 2 through 255 inclusive. This is a caller defined "thread number" and is used to match the response message with the correct user application thread. @@ -64,7 +64,7 @@ If the ID value is not in the proper range, the attempt to make the call will fa &space Messages which are received while waiting for the response are queued on a &ital(normal) receive queue and will be delivered to the user application with the next invocation -of &ital( rmr_mt_rcv() ) or &ital( rmr_rvv_msg().) +of &ital(rmr_mt_rcv()) or &ital(rmr_rvv_msg().) by RMR, and are returned to the user application when &cw(rmr_rcv_msg) is invoked. These messages are returned in th order received, one per call to &cw(rmr_rcv_msg.) @@ -84,7 +84,7 @@ RMr will compare &bold(all) of the bytes in the field, so the caller must ensure that they are set correctly to avoid missing the response message. (The application which returns the response message is also expected to ensure that the return buffer has the matching transaction ID. This can be done transparently if -the application uses the &ital( rmr_rts_msg() ) function and does not adjust the +the application uses the &ital(rmr_rts_msg()) function and does not adjust the transaction ID. .** pull in common retry text diff --git a/doc/src/man/rmr_mt_rcv.3.xfm b/doc/src/man/rmr_mt_rcv.3.xfm index d5c31b2..9584c49 100644 --- a/doc/src/man/rmr_mt_rcv.3.xfm +++ b/doc/src/man/rmr_mt_rcv.3.xfm @@ -114,7 +114,7 @@ indicate either &cw(RMR_OK) or &half_space &di(RMR_ERR_NOTSUPP) The multi-threaded option was not enabled when RMr was -initialised. See the man page for &ital(rmr_init() ) for details. +initialised. See the man page for &ital(rmr_init()) for details. &half_space &di(RMR_ERR_RCVFAILED) A hard error occurred preventing the receive from completing. diff --git a/doc/src/man/rmr_send_msg.3.xfm b/doc/src/man/rmr_send_msg.3.xfm index d9cc620..36812c0 100644 --- a/doc/src/man/rmr_send_msg.3.xfm +++ b/doc/src/man/rmr_send_msg.3.xfm @@ -67,7 +67,7 @@ The state in this buffer will reflect the overall send operation state and shoul &space When the message cannot be successfully sent this function will return the unsent (original) message buffer with the state set to indicate the reason for failure. -The value of &ital( errno ) may also be set to reflect a more detailed failure reason if it +The value of &ital(errno) may also be set to reflect a more detailed failure reason if it is known. &space diff --git a/doc/src/man/rmr_set_stimeout.3.xfm b/doc/src/man/rmr_set_stimeout.3.xfm index ca091ac..4f5dd35 100644 --- a/doc/src/man/rmr_set_stimeout.3.xfm +++ b/doc/src/man/rmr_set_stimeout.3.xfm @@ -44,35 +44,35 @@ rmr_mbuf_t* rmr_set_stimeout( void* vctx, int rloops ); &h2(DESCRIPTION) The &cw(rmr_set_stimeout) function sets the configuration for how RMr will retry -message send operations which complete with either a &ital( timeout ) or &ital( again ) +message send operations which complete with either a &ital(timeout) or &ital(again) completion value. (Send operations include all of the possible message send -functions: &ital( rmr_send_msg(), rmr_call(), rmr_rts_msg() ) and &ital( rmr_wh_send_msg(). ) -The &ital( rloops ) parameter sets the maximum number of retry loops +functions: &ital(rmr_send_msg(), rmr_call(), rmr_rts_msg()) and &ital(rmr_wh_send_msg().) +The &ital(rloops) parameter sets the maximum number of retry loops that will be attempted before giving up and returning the unsuccessful state to the user application. -Each retry loop is approximately 1000 attempts, and RMr does &bold( not ) invoke any sleep +Each retry loop is approximately 1000 attempts, and RMr does &bold(not) invoke any sleep function between retries in the loop; a small, 1 mu-sec, sleep is executed between loop -sets if the &ital( rloops ) value is greater than 1. +sets if the &ital(rloops) value is greater than 1. .sp &h3(Disabling Retries) -By default, the send operations will execute with an &ital( rloop ) setting of 1; each send +By default, the send operations will execute with an &ital(rloop) setting of 1; each send operation will attempt to resend the message approximately 1000 times before giving up. If the user application does not want to have send operations retry when the underlying -transport mechanism indicates &ital( timeout ) or &ital( again, ) the application should -invoke this function and pass a value of 0 (zero) for &ital( rloops. ) -With this setting, all RMr send operations will attempt a send operation only &bold( once, ) +transport mechanism indicates &ital(timeout) or &ital(again,) the application should +invoke this function and pass a value of 0 (zero) for &ital(rloops.) +With this setting, all RMr send operations will attempt a send operation only &bold(once,) returning immediately to the caller with the state of that single attempt. &h2(RETURN VALUE) -This function returns a -1 to indicate that the &ital( rloops ) value could not be set, and -the value &ital( RMR_OK ) to indicate success. +This function returns a -1 to indicate that the &ital(rloops) value could not be set, and +the value &ital(RMR_OK) to indicate success. &h2(ERRORS) -Currently errno is &bold( not ) set by this function; the only cause of a failure is an -invalid context ( .sm &ital( vctx ) .sm ) pointer. +Currently errno is &bold(not) set by this function; the only cause of a failure is an +invalid context ( .sm &ital(vctx) .sm ) pointer. &h2(EXAMPLE) The following is a simple example of how the &cw(rmr_set_stimeout) function is called. diff --git a/doc/src/man/rmr_str2meid.3.xfm b/doc/src/man/rmr_str2meid.3.xfm index 5d336b6..28f85c6 100644 --- a/doc/src/man/rmr_str2meid.3.xfm +++ b/doc/src/man/rmr_str2meid.3.xfm @@ -48,7 +48,7 @@ The &cw(rmr_str2meid) function will copy the string pointed to by src to the managed equipment ID (meid) field in the given message. The field is a fixed length, gated by the constant &cw(RMR_MAX_MEID) and if string length is larger than this value, then &bold(nothing) will be copied. (Note, this differs slightly from the -behaviour of the &cw( lrmr_bytes2meid() ) function.) +behaviour of the &cw(lrmr_bytes2meid()) function.) &h2(RETURN VALUE) On success, the value RMR_OK is returned. diff --git a/doc/src/man/rmr_str2xact.3.xfm b/doc/src/man/rmr_str2xact.3.xfm index 6f6046f..e27c5f6 100644 --- a/doc/src/man/rmr_str2xact.3.xfm +++ b/doc/src/man/rmr_str2xact.3.xfm @@ -48,7 +48,7 @@ The &cw(rmr_str2xact) function will copy the string pointed to by src to the transaction ID (xaction) field in the given message. The field is a fixed length, gated by the constant &cw(RMR_MAX_XID) and if string length is larger than this value, then &bold(nothing) will be copied. (Note, this differs slightly from the -behaviour of the &cw( lrmr_bytes2xact() ) function.) +behaviour of the &cw(lrmr_bytes2xact()) function.) &beg_dlist(.75i : ^&bold_font ) &h2(RETURN VALUE) diff --git a/doc/src/markdown.im b/doc/src/markdown.im index d922fc9..17ae572 100644 --- a/doc/src/markdown.im +++ b/doc/src/markdown.im @@ -37,6 +37,7 @@ .hn off +.dv esc : .** rst needs an escape for some things .** these macros are common for prfm/tfm, markdown will override some .dv indent .ll -.5i .in +.25i diff --git a/doc/src/roff.im b/doc/src/roff.im index eef25de..4c00d23 100644 --- a/doc/src/roff.im +++ b/doc/src/roff.im @@ -50,6 +50,8 @@ .dv center_start .br ^^.ce 999 .dv center_end .br ^.ce 0 +.dv esc : .** rst needs an escape for some things + .dv line_len ^^.ll $1 .dv space .br ^^.sp 1 .br .dv half_space .br ^^.sp 1 .br diff --git a/doc/src/rst.im b/doc/src/rst.im index ebbbefe..e2444b1 100644 --- a/doc/src/rst.im +++ b/doc/src/rst.im @@ -62,6 +62,7 @@ .in 0i .** bloody rst is indention sensitive like markdown; sheesh + .dv esc \ : .** bloody need to escape _ and * at the end of a word .dv line_len .ll $1 .dv space .sp 1 .dv half_space .sp 1 diff --git a/doc/src/rtd/Makefile b/doc/src/rtd/Makefile index 7e49946..4c64278 100644 --- a/doc/src/rtd/Makefile +++ b/doc/src/rtd/Makefile @@ -37,7 +37,6 @@ docs = config-deploy developer-guide user-guide rel-notes overview all:: $(docs:%=%.rst) $(docs:%=%.txt) $(docs:%=%.md) - echo ">>> rm rel-notes.xfm" rel-notes.xfm: ksh fmt_changes.ksh >rel-notes.xfm diff --git a/doc/src/rtd/README b/doc/src/rtd/README index b6f4acd..c7dd309 100644 --- a/doc/src/rtd/README +++ b/doc/src/rtd/README @@ -15,3 +15,11 @@ single make. While it is possible to convert X to Y, a true document composition language is far better at geneating readable Postscript output with embedded figures as well as text and tables. +CAUTION: +The RST syntax is as bad as python when it comes to dealing with +spaces. For example &bold( foo ) will insert spaces after the initial +bold trigger, and before the trailing bold trigger which will throw +the tox validation into a tizzy. Further, something like 'void *' +and 'rmr_ ' does as well. If needed, use the defined escape macro +to add an escape in such situations; it should only generate for RST +and not impact other output formats. diff --git a/doc/src/rtd/developer-guide.xfm b/doc/src/rtd/developer-guide.xfm index 3cf3bb8..ebde32a 100644 --- a/doc/src/rtd/developer-guide.xfm +++ b/doc/src/rtd/developer-guide.xfm @@ -78,7 +78,7 @@ module (e.g. rmr_nng.c) will directly include other RMR modules, rather than depending on referencing the internal functions during linking. While this is an infrequently used approach, it does mean that there are very few functions visible for the user application to reference, all of them having -the prefix &cw(rmr_,) while allowing internal functions to have shorter names +the prefix &cw(rmr&{esc}_,) while allowing internal functions to have shorter names while still being meaningful. &h2(Coding Style) diff --git a/doc/src/txt.im b/doc/src/txt.im index 6599928..bed0d9c 100644 --- a/doc/src/txt.im +++ b/doc/src/txt.im @@ -57,6 +57,8 @@ .dv lic2 + .dv lic3 - +.dv esc : .** rst needs an escape for some things + .dv line_len .ll $1 .dv space .sp 1 .dv mult_space .sp $1 diff --git a/docs/_static/logo.png b/docs/_static/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e54843d5c7743535a9d238e0399e4b003f178a43 GIT binary patch literal 10661 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