Skip to content

Commit

Permalink
Fix enums using assignment operators (#175)
Browse files Browse the repository at this point in the history
Previously the enumerator parsing logic utilized the same logic as the macro parsing logic.
These are actually disparate logic. Now the enumerator logic uses the common base logic, with dedicated handling for the format_name() to only return the enumerator's name.
speedyleion authored Jun 29, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent af6ab9e commit 3415f50
Showing 3 changed files with 92 additions and 50 deletions.
10 changes: 9 additions & 1 deletion src/sphinx_c_autodoc/loader.py
Original file line number Diff line number Diff line change
@@ -348,13 +348,21 @@ def get_parsed_declaration(self) -> str:
return f"{self.name}({', '.join(tokens)})"


class DocumentedEnumerator(DocumentedMacro):
class DocumentedEnumerator(DocumentedObject):
"""
An enumerator, the constant values in an enum
"""

type_ = "enumerator"

def format_name(self) -> str:
"""
The name of the object.
For things like functions and others this will include the return type.
"""
return self.name


class DocumentedMember(DocumentedObject):
"""
22 changes: 22 additions & 0 deletions tests/assets/c_source/issue_174.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Test case example of the issue that was reported in
// https://github.com/speedyleion/sphinx-c-autodoc/issues/174

/**
* My Define
*/
#define MY_BITMASK 0x8000U

/**
* My Define mask
*/
#define MY_MASKED( base_enum ) ((base_enum) | MY_BITMASK )

/**
* My enum
*/
typedef enum {
VALUE_0, /**< my value 0*/
VALUE_1, /**< my value 1*/
VALUE_2 = MY_MASKED( VALUE_0 ), /**< my value 2*/
VALUE_3 = MY_MASKED( VALUE_1 ), /**< my value 3*/
} my_value_e;
110 changes: 61 additions & 49 deletions tests/directives/test_autocenum.py
Original file line number Diff line number Diff line change
@@ -7,56 +7,68 @@

from sphinx.ext.autodoc.directive import AutodocDirective

some_enum = """\
enum some_enum
If you want to document the enumerators with napoleon
then you use the section title Enumerators:.
class TestAutoCEnum:
enumerator THE_FIRST_ENUM
Used for the first item
Documentation in a comment for THE_FIRST_ITEM. Note this is trailing, for some reason clang will apply leading comments to all the enumerators
enumerator THE_SECOND_ENUM
Second verse same as the first.
enumerator THE_THIRD_ENUM
Not once, note twice, but thrice.
enumerator THE_LAST_ENUM
Just to be sure."""

my_value_e = """\
enum my_value_e
My enum
enumerator VALUE_0
my value 0
enumerator VALUE_1
my value 1
enumerator VALUE_2
my value 2
enumerator VALUE_3
my value 3"""

doc_data = [
("example.c::some_enum", some_enum),
("issue_174.c::my_value_e", my_value_e),
]


@pytest.mark.parametrize("enum, expected_doc", doc_data)
def test_doc(enum, expected_doc, sphinx_state):
"""
Testing class for the autocenum directive for use in enums
Tests the restructured text output returned by the directive.
"""
directive = AutodocDirective(
"autocenum",
[enum],
{"members": None},
None,
None,
None,
None,
sphinx_state,
None,
)
output = directive.run()

# First item is the index entry
assert 2 == len(output)
body = output[1]

some_enum = """\
enum some_enum
If you want to document the enumerators with napoleon
then you use the section title Enumerators:.
enumerator THE_FIRST_ENUM
Used for the first item
Documentation in a comment for THE_FIRST_ITEM. Note this is trailing, for some reason clang will apply leading comments to all the enumerators
enumerator THE_SECOND_ENUM
Second verse same as the first.
enumerator THE_THIRD_ENUM
Not once, note twice, but thrice.
enumerator THE_LAST_ENUM
Just to be sure."""

doc_data = [
("example.c::some_enum", some_enum),
]

@pytest.mark.parametrize("enum, expected_doc", doc_data)
def test_doc(self, enum, expected_doc, sphinx_state):
"""
Tests the restructured text output returned by the directive.
"""
directive = AutodocDirective(
"autocenum",
[enum],
{"members": None},
None,
None,
None,
None,
sphinx_state,
None,
)
output = directive.run()

# First item is the index entry
assert 2 == len(output)
body = output[1]

# For whatever reason the as text comes back with double spacing, so we
# knock it down to single spacing to make the expected string smaller.
assert body.astext().replace("\n\n", "\n") == dedent(expected_doc)
# For whatever reason the as text comes back with double spacing, so we
# knock it down to single spacing to make the expected string smaller.
assert body.astext().replace("\n\n", "\n") == dedent(expected_doc)

0 comments on commit 3415f50

Please sign in to comment.