libctf: new enum-related API functions: request for better names
Nick Alcock
nick.alcock@oracle.com
Wed May 22 10:31:57 GMT 2024
On 21 May 2024, Nick Alcock uttered the following:
>> function. However, a new API for this would be much less flexible... The
>> above function allows me to run code for each enum type, before and
>> after handling all of the enumerators for that type. A
>> ctf_enumerator_next() function cannot really give me that information.
> [...]
>
> I think it could if properly defined, though the definition would be a
> bit odd. Something like:
>
> /* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
> NULL at end of iteration or error, and optionally passing back the
> enumerand's integer VALue. On end of iteration, sets ECTF_NEXT_END.
> At end of each enum, sets ECTF_NEXT_ENUM_END (and iteration
> continues). */
>
> const char *ctf_enumerator_next (ctf_dict_t *fp, ctf_next_t **it,
> ctf_id_t *enum, int *val);
>
> With that in place, you can do this:
>
> const char *enumrator;
> ctf_id_t enum_id;
> int64_t value;
>
> while ((enumerator = ctf_enumerator_next (dict, &next, &enum_id, &value)) != NULL
> || ctf_errno (dict) == ECTF_NEXT_ENUM_END) {
> {
> if (ctf_errno (dict) == ECTF_NEXT_ENUM_END) {
> /* end-of-this-enum-type stuff */
> continue;
> }
> /* one-enumerand stuff... */
> }
> if (ctf_errno (dict) != ECTF_NEXT_END) {
> ctf_next_destroy (next);
> /* oops, error... */
> }
>
> Now possibly this is too different from the way other iterators work,
> I'm not sure... the repetition of ECTF_NEXT_ENUM_END is ugly but there
> is probably a less ugly way if I just thought for a moment :)
No no that's way too complex! You can do it with a simple
ctf_enumerator_next() that does nothing special at all other than return
different enumeration constants one after the other like any other
iterator would (assuming it does it in a sane way and returns all the
constants for one enum before moving to the next, which, well, yes of
course it will):
const char *enumerator;
ctf_id_t old_enum_id = CTF_ERR, enum_id;
int64_t value;
while ((enumerator = ctf_enumerator_next (dict, &next, &enum_id, &value)) != NULL)
{
if (old_enum_id != enum_id) {
/* end-of-this-enum-type stuff, then fall through */
}
}
if (ctf_errno (dict) != ECTF_NEXT_END) {
ctf_next_destroy (next);
/* oops, error... */
}
if (old_enum_id != CTF_ERR) {
/* end-of-the-last-enum-type stuff */
}
It's a bit clunky because you have to double some stuff up, but that's
common in C loop-like constructs and easily fixed by splitting a bit out
into another function.
More information about the Binutils
mailing list