lib: strictly type function return status enumerations
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Sun, 30 Jun 2019 06:26:38 +0000 (02:26 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 3 Jul 2019 04:43:28 +0000 (00:43 -0400)
commitd24d56638469189904fb6ddbb3c725817b3e9417
tree8181789a3554d38f65ecb9ff72f6a81743a7a188
parent15caa1ca4fac30bd196602bd136e48fda3892de2
lib: strictly type function return status enumerations

Rigour strikes again.

This patch makes each function (or group of related functions) of the
library which returns a status enumeration return its own,
function-specific status enumeration.

For example, where bt_graph_run() used to return the generic
`bt_graph_status` type, it now returns `bt_graph_run_status`.

The benefits are:

* Each function defines its own set of available status codes. With
  appropriate compiler warnings, you can catch comparisons between a
  returned status and an incompatible enumerator, and assignments of
  incompatible enumerators. For example, with clang 8:

      file.c:13:13: warning: implicit conversion from enumeration type
      'enum bt_component_class_init_method_status'
      to different enumeration type
      'enum bt_component_class_port_connected_method_status'
      [-Wenum-conversion]
        bt_component_class_port_connected_method_status status =
          BT_COMPONENT_CLASS_INIT_METHOD_STATUS_ERROR;

  This was not possible before because all the status-returning
  functions of a given header could possibly return any value defined by
  the header-wide status enumeration.

* A function's possible return values are self-documented: there's no
  need to document that a given function can only return some subset of
  the header-wide status enumerators.

* In future minor releases of Babeltrace 2, we can add new status codes
  for a specific function.

* Some smart IDEs will list the possible enumerators when checking the
  return value of a function or when returning a value from a function.

To uniformize the status enumerator integer values, the new
`<babeltrace2/func-status.h>` public header contains definitions for all
the possible status codes. They are definitions instead of enumerators
because they are not meant to be used directly by user code.

To make sure a user does not write:

    #include <babeltrace2/func-status.h>

to use the `__BT_FUNC_STATUS_*` definitions directly (which would
inhibit the precious type checking that this patch is all about), the
compiler will show the error:

> Do NOT include <babeltrace2/func-status.h> in user code.

unless you define `__BT_FUNC_STATUS_ENABLE` before including the header.

Each public header which needs `__BT_FUNC_STATUS_*` definitions to
define its own status enumerations does:

    /* For __BT_FUNC_STATUS_* */
    #define __BT_FUNC_STATUS_ENABLE
    #include <babeltrace2/func-status.h>
    #undef __BT_FUNC_STATUS_ENABLE

at the beginning of the file, and:

    #include <babeltrace2/undef-func-status.h>

at the end of the file. The `<babeltrace2/undef-func-status.h>` header
cancels all the existing `__BT_FUNC_STATUS_*` definitions so that they
are not available to user code.

Within the library, `"lib/func-status.h"` uses the definitions of
`<babeltrace2/func-status.h>` to define its own, similar definitions,
but without the `__` prefix for improved internal code readability.
Internal library code does not need to "undefine" those definitions.

As this system guarantees that any public status enumerator is an alias
of one of the `__BT_FUNC_STATUS_*` definitions, the library code never
uses the function-specific status enumerators directly: it always uses
one of the `BT_FUNC_STATUS_*` definitions found in
`"lib/func-status.h"`. This made it easier to adapt existing code. This
also allows to pass such status codes easily between internal and public
functions because they are `int` values until they finally reach public
enumeration types where they are implicitly casted.

When an internal (hidden, static) function returns a status code, it now
returns `int`, using one of the `BT_FUNC_STATUS_*` values, where this
could be used by at least two functions returning different public
status enumerations.

In internal headers, all the bt_*_status_string() are removed in favor
of bt_common_func_status_string() which returns only the suffix string
(e.g., `OK`, `ERROR`, `OVERFLOW`). This function is typically used when
logging.

The `*_NOMEM` enumerators are renamed to `*_MEMORY_ERROR` to make this
clear and remove this abbreviation which was the only one amongst other
public status enumerators.

Because the Python bindings are within the Babeltrace project, they use
the `__BT_FUNC_STATUS_*` definitions internally. Those values will not
change in the future anyway. All the _handle_*status() and
bt2.utils._handle_ret() functions are removed in favor of
bt2.utils._handle_func_status() which can handle all the possible status
codes and raise a corresponding exception, possibly with a given
message.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I3966ac0e691219102897920617711c518c34fbdf
157 files changed:
extras/gen-babeltrace-h.py
include/Makefile.am
include/babeltrace2/babeltrace.h
include/babeltrace2/func-status.h [new file with mode: 0644]
include/babeltrace2/graph/component-class-const.h
include/babeltrace2/graph/component-class-filter.h
include/babeltrace2/graph/component-class-sink.h
include/babeltrace2/graph/component-class-source.h
include/babeltrace2/graph/component-class.h
include/babeltrace2/graph/graph-const.h
include/babeltrace2/graph/graph.h
include/babeltrace2/graph/message-iterator-const.h [deleted file]
include/babeltrace2/graph/message-iterator.h [new file with mode: 0644]
include/babeltrace2/graph/port-output-message-iterator.h
include/babeltrace2/graph/query-executor-const.h
include/babeltrace2/graph/query-executor.h
include/babeltrace2/graph/self-component-filter.h
include/babeltrace2/graph/self-component-port-input-message-iterator.h
include/babeltrace2/graph/self-component-sink.h
include/babeltrace2/graph/self-component-source.h
include/babeltrace2/graph/self-component.h
include/babeltrace2/graph/self-message-iterator.h
include/babeltrace2/plugin/plugin-const.h
include/babeltrace2/plugin/plugin-dev.h
include/babeltrace2/trace-ir/clock-class-const.h
include/babeltrace2/trace-ir/clock-class.h
include/babeltrace2/trace-ir/clock-snapshot-const.h
include/babeltrace2/trace-ir/event-class-const.h
include/babeltrace2/trace-ir/event-class.h
include/babeltrace2/trace-ir/event-const.h
include/babeltrace2/trace-ir/event.h
include/babeltrace2/trace-ir/field-class-const.h
include/babeltrace2/trace-ir/field-class.h
include/babeltrace2/trace-ir/field-const.h
include/babeltrace2/trace-ir/field.h
include/babeltrace2/trace-ir/packet-const.h
include/babeltrace2/trace-ir/packet.h
include/babeltrace2/trace-ir/stream-class-const.h
include/babeltrace2/trace-ir/stream-class.h
include/babeltrace2/trace-ir/stream-const.h
include/babeltrace2/trace-ir/stream.h
include/babeltrace2/trace-ir/trace-class-const.h
include/babeltrace2/trace-ir/trace-class.h
include/babeltrace2/trace-ir/trace-const.h
include/babeltrace2/trace-ir/trace.h
include/babeltrace2/types.h
include/babeltrace2/undef-func-status.h [new file with mode: 0644]
include/babeltrace2/value-const.h
include/babeltrace2/value.h
src/bindings/python/bt2/bt2/__init__.py.in
src/bindings/python/bt2/bt2/clock_class.py
src/bindings/python/bt2/bt2/clock_snapshot.py
src/bindings/python/bt2/bt2/component.py
src/bindings/python/bt2/bt2/event_class.py
src/bindings/python/bt2/bt2/field.py
src/bindings/python/bt2/bt2/field_class.py
src/bindings/python/bt2/bt2/graph.py
src/bindings/python/bt2/bt2/message_iterator.py
src/bindings/python/bt2/bt2/native_bt.i
src/bindings/python/bt2/bt2/native_bt_component.i
src/bindings/python/bt2/bt2/native_bt_component_class.i
src/bindings/python/bt2/bt2/native_bt_graph.i
src/bindings/python/bt2/bt2/native_bt_logging.i
src/bindings/python/bt2/bt2/native_bt_message_iterator.i
src/bindings/python/bt2/bt2/native_bt_plugin.i
src/bindings/python/bt2/bt2/native_bt_trace.i
src/bindings/python/bt2/bt2/native_bt_trace_class.i
src/bindings/python/bt2/bt2/native_bt_value.i
src/bindings/python/bt2/bt2/plugin.py
src/bindings/python/bt2/bt2/port.py
src/bindings/python/bt2/bt2/query_executor.py
src/bindings/python/bt2/bt2/stream_class.py
src/bindings/python/bt2/bt2/trace.py
src/bindings/python/bt2/bt2/trace_class.py
src/bindings/python/bt2/bt2/utils.py
src/bindings/python/bt2/bt2/value.py
src/cli/babeltrace2-cfg-cli-args.c
src/cli/babeltrace2-cfg.c
src/cli/babeltrace2.c
src/common/common.h
src/lib/Makefile.am
src/lib/func-status.h [new file with mode: 0644]
src/lib/graph/component-class-sink-colander.c
src/lib/graph/component-class.c
src/lib/graph/component-filter.c
src/lib/graph/component-sink.c
src/lib/graph/component-source.c
src/lib/graph/component.c
src/lib/graph/component.h
src/lib/graph/connection.h
src/lib/graph/graph.c
src/lib/graph/graph.h
src/lib/graph/iterator.c
src/lib/graph/message/iterator.h
src/lib/graph/query-executor.c
src/lib/graph/query-executor.h
src/lib/plugin/plugin-so.c
src/lib/plugin/plugin-so.h
src/lib/plugin/plugin.c
src/lib/plugin/plugin.h
src/lib/trace-ir/clock-class.c
src/lib/trace-ir/clock-class.h
src/lib/trace-ir/clock-snapshot.c
src/lib/trace-ir/event-class.c
src/lib/trace-ir/field-class.c
src/lib/trace-ir/field.c
src/lib/trace-ir/packet.c
src/lib/trace-ir/stream-class.c
src/lib/trace-ir/stream.c
src/lib/trace-ir/trace-class.c
src/lib/trace-ir/trace.c
src/lib/value.c
src/lib/value.h
src/plugins/ctf/common/msg-iter/msg-iter.c
src/plugins/ctf/fs-sink/fs-sink-trace.c
src/plugins/ctf/fs-sink/fs-sink.c
src/plugins/ctf/fs-sink/fs-sink.h
src/plugins/ctf/fs-src/data-stream-file.c
src/plugins/ctf/fs-src/data-stream-file.h
src/plugins/ctf/fs-src/fs.c
src/plugins/ctf/fs-src/fs.h
src/plugins/ctf/fs-src/query.c
src/plugins/ctf/fs-src/query.h
src/plugins/ctf/lttng-live/lttng-live.c
src/plugins/ctf/lttng-live/lttng-live.h
src/plugins/ctf/lttng-live/viewer-connection.c
src/plugins/ctf/lttng-live/viewer-connection.h
src/plugins/lttng-utils/debug-info/debug-info.c
src/plugins/lttng-utils/debug-info/debug-info.h
src/plugins/lttng-utils/debug-info/trace-ir-data-copy.c
src/plugins/lttng-utils/debug-info/trace-ir-mapping.c
src/plugins/lttng-utils/debug-info/trace-ir-metadata-copy.c
src/plugins/lttng-utils/debug-info/trace-ir-metadata-field-class-copy.c
src/plugins/text/details/details.c
src/plugins/text/details/details.h
src/plugins/text/details/write.c
src/plugins/text/dmesg/dmesg.c
src/plugins/text/dmesg/dmesg.h
src/plugins/text/pretty/pretty.c
src/plugins/text/pretty/pretty.h
src/plugins/utils/counter/counter.c
src/plugins/utils/counter/counter.h
src/plugins/utils/dummy/dummy.c
src/plugins/utils/dummy/dummy.h
src/plugins/utils/muxer/muxer.c
src/plugins/utils/muxer/muxer.h
src/plugins/utils/trimmer/trimmer.c
src/plugins/utils/trimmer/trimmer.h
src/python-plugin-provider/python-plugin-provider.c
tests/bindings/python/bt2/test_clock_class.py
tests/bindings/python/bt2/test_graph.py
tests/bindings/python/bt2/test_query_executor.py
tests/lib/plugin.c
tests/lib/test-plugin-plugins/minimal.c
tests/lib/test-plugin-plugins/sfs.c
tests/lib/test_trace_ir_ref.c
tests/plugins/src.ctf.fs/query/test_query_trace_info.py
This page took 0.040178 seconds and 4 git commands to generate.