NordicSemiconductor / zcbor

Low footprint C/C++ CBOR library and Python tool providing code generation from CDDL descriptions.
Apache License 2.0
105 stars 34 forks source link

Complex enum doesn't start at indicated value #433

Open aangert opened 1 month ago

aangert commented 1 month ago

When generating code the indicated value in complex enums is ignored. In the example UNIT_UNDEFINED should be of value 1, but this is missing from the generated code, causing it to have a value of 0. The error occurs regardless of the number and value of items in AllUnits.

This issue might be an extension of https://github.com/NordicSemiconductor/zcbor/issues/14

CDDL:

Pet = [
    name: [ +tstr ],
    unit: AllUnits
]

AllUnits =
    (UNIT_UNDEFINED                 :  1) /
    UnitElectrical,
    ; extension point

UnitElectrical =
    (UNIT_ELECTRICAL_SI_VOLTAGE     :  2) /
    (UNIT_ELECTRICAL_SI_CURRENT     :  3) /
    (UNIT_ELECTRICAL_SI_RESISTANCE  :  4) /
    (UNIT_ELECTRICAL_SI_CONDUCTANCE :  5)
struct UnitElectrical_r {
    enum {
        UnitElectrical_UNIT_ELECTRICAL_SI_VOLTAGE_c = 2,
        UnitElectrical_UNIT_ELECTRICAL_SI_CURRENT_c = 3,
        UnitElectrical_UNIT_ELECTRICAL_SI_RESISTANCE_c = 4,
        UnitElectrical_UNIT_ELECTRICAL_SI_CONDUCTANCE_c = 5,
    } UnitElectrical_choice;
};

struct AllUnits_r {
    union {
        struct UnitElectrical_r AllUnits_UnitElectrical_m;
    };
    enum {
        AllUnits_UNIT_UNDEFINED_c,//missing assigned value 1
        AllUnits_UnitElectrical_m_c,
    } AllUnits_choice;
};
oyvindronningstad commented 2 weeks ago

Using the uint values from the CDDL is an optimization that is applied sometimes. Right now, it's only applied in the trivial cases, where a union contains only unambiguous integers. In your example, the AllUnits union contains an integer and another union.

Thanks for the report, I will track it as a possible improvement.