Closed kdschlosser closed 9 months ago
I expanded the output for the debugging results. It look like for some reason it is marking the _lv_res_t
enum as a typedef when it isn't.
State : 100
Stack : translation_unit storage_class_specifier declaration_specifiers_no_type_opt . LexToken(ID,'_lv_res_t',52,6995)
Action : Reduce rule [declaration_specifiers_no_type -> storage_class_specifier declaration_specifiers_no_type_opt] with ['typedef',None] and goto state 25
Result : <dict @ 0x7f37f6256600> ({'qual': [], 'storage': ['typedef'], 'type': [], 'function': [], 'alignment': []})
Please add a minimal, reproducible example
A small .c
file without any preprocessor directives that you observe the issue on.
It's right there. I just gave you an example.
enum _lv_res_t {
LV_RES_INV = 0, /*Typically indicates that the object is deleted (become invalid) in the action
function or an operation was failed*/
LV_RES_OK, /*The object is valid (no deleted) after the action*/
};
typedef _lv_res_t lv_res_t;
This example still has comments that need to be removed manually. I asked for code that can be fed to pycparser directly without the preprocessor (which often obscures issue reports).
In any case, the code is invalid standard C, I believe, because the compiler does not know what _lv_res_t
is.
Trying your fragment with gcc -std=c99
, I get:
error: unknown type name ‘_lv_res_t’
7 | typedef _lv_res_t lv_res_t;
| ^~~~~~~~~
The right way to write this typedef would be:
typedef enum _lv_res_t lv_res_t;
OK so I have done what you stated and this is what happens.
enum _lv_meter_indicator_type_t {
LV_METER_INDICATOR_TYPE_NEEDLE_IMG,
LV_METER_INDICATOR_TYPE_NEEDLE_LINE,
LV_METER_INDICATOR_TYPE_SCALE_LINES,
LV_METER_INDICATOR_TYPE_ARC,
};
typedef enum _lv_meter_indicator_type_t lv_meter_indicator_type_t;
Decl(name=None,
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=Enum(name='_lv_meter_indicator_type_t',
values=EnumeratorList(enumerators=[Enumerator(name='LV_METER_INDICATOR_TYPE_NEEDLE_IMG',
value=None
),
Enumerator(name='LV_METER_INDICATOR_TYPE_NEEDLE_LINE',
value=None
),
Enumerator(name='LV_METER_INDICATOR_TYPE_SCALE_LINES',
value=None
),
Enumerator(name='LV_METER_INDICATOR_TYPE_ARC',
value=None
)
]
)
),
init=None,
bitsize=None
)
TypeDecl(declname='lv_meter_indicator_type_t',
quals=[
],
align=None,
type=Enum(name='_lv_meter_indicator_type_t',
values=None
)
)
see the issue there.
lv_meter_indicator_type_t
has the type of _lv_meter_indicator_type_t
but it has no values.
Those values should be apart of the lv_meter_indicator_type_t
type because lv_meter_indicator_type_t
is an alias for _lv_meter_indicator_type_t
the type for lv_meter_indicator_type_t
should be the same instance as the type used in the Decl at the top.
Oh and I am not sure why I am able to run the code through the preprocessor and it doesn't error at all. It also works with DOXYGEN without any issues. The original example I am referring to.
Yes, that's how it works. pycparser just produces an AST for you, it doesn't do any semantic or type analysis. Note also that just:
typedef enum _lv_meter_indicator_type_t lv_meter_indicator_type_t;
... is perfectly valid C. The enum
type doesn't have to be declared.
The AST you have from pycparser has all the information you need -- you can see the type the typedef
is referring to, find that type in the AST and extract whatever you need from it.
There is no link between the 2 enumerations made?.. what you are telling me is I have to iterate over the entire ast again in order to locate the type used in the typedef? That's crazy to have to do that. There should be some kind of a link between a typedef and it's parent type if there is one available.
so if I use this code
typedef enum _example {
some_enumeration=0,
} example;
is some_enumeration
a descendant of example
?
I believe it is.
enum _example {
some_enumeration=0,
};
typedef enum _example example;
but it's not if I do this?...
They are both the same thing. They do the same thing...
The following code is being use to keep memory use in check when returning an enumeration from a function. The 3 byte savings is needed. The issue is when generating documentation unless I change the type to the actual enumeration the path back to the enumeration will not be completed. The following code fixes that issue when documentation is generated for the C code.
There is a binding that is made for Python that uses pycparser to read the C code. The binding makes things more pythonic and in a class arrangement. I would like to be able to pull the documentation from the c library and align it correctly with the python code. This shouldn't be an issue except when I set the macro for DOXYGEN and run it through pycparser it errors out on
typedef _lv_res_t lv_res_t;
. It doesn't error if I do not have the DOXYGEN macro set. I need it set in order to make the correct link in the documentation in order to have the enum values correctly tied to a functions return value in the documentation.Here is the debugging output from pycparser