Skip to content

enumtypes: skip generation of "last" members #4520

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 29, 2025

Conversation

kleisauke
Copy link
Member

@kleisauke kleisauke commented May 16, 2025

We probably don't want to expose these "last" members to language bindings.

Generated enumtypes.c diff: https://gist.github.com/kleisauke/97d3e7d01df0a79b4b9179ea201e053e

See also: libvips/pyvips#537.

kleisauke added a commit to kleisauke/pyvips that referenced this pull request May 16, 2025
@jcupitt
Copy link
Member

jcupitt commented May 16, 2025

I suppose we could also just remove the _LAST members and do it at runtime instead. We could have some compatibility defines which fetched the n_values field:

https://docs.gtk.org/gobject/struct.EnumClass.html

We wouldn't be able to get the size of the enum statically, but maybe that's not too bad?

ruby-vips, php-vips etc might need changes too.

Maybe that's too big a change.

@kleisauke
Copy link
Member Author

kleisauke commented May 16, 2025

I think removing the _LAST members would cause a lot of issues downstream, e.g. sharp uses to mean "unset", see:
https://github.com/lovell/sharp/blob/v0.34.1/src/pipeline.h#L380-L381

@kleisauke
Copy link
Member Author

I checked NetVips, php-vips, pyvips, and ruby-vips, none of these language bindings appear to expose these _LAST enum members. However, you might still be able to pass them as string literals, if supported (NetVips no longer supports this).

My only concern is the potential vips_enum_from_nick() API break, though it would guarantee that these _LAST members aren't used further downstream. For example, this would segfault on the master branch:

$ vipsthumbnail zebra.jpg --smartcrop=last
Segmentation fault (core dumped)

due to:

g_assert_not_reached();

But with this PR, it would error with:

$ vipsthumbnail zebra.jpg --smartcrop=last
vipsthumbnail: unable to thumbnail zebra.jpg
vipsthumbnail: enum 'VipsInteresting' has no member 'last', should be one of: none, centre, entropy, attention, low, high, all

@kleisauke
Copy link
Member Author

As an experiment, here's a branch that removes these _LAST enum members instead:
master...kleisauke:enums-remove-last-member

@jcupitt
Copy link
Member

jcupitt commented May 17, 2025

I think we'd need something for uses like:

    if (mode[i] < 0 ||
        mode[i] >= VIPS_BLEND_MODE_LAST) {

Maybe:

// tiny utility func
GEnumClass *vips__get_enum_class(const char *class_name);

#define VIPS_BLEND_MODE_LAST (vips__get_enum_class("VipsBlendMode")->n_values)

Or perhaps just:

// returns n_values
int vips__get_enum_last(const char *class_name);


    if (mode[i] < 0 ||
        mode[i] > vips__get_enum_last("VipsBlendMode")) {

What do you think?

kleisauke added a commit to kleisauke/pyvips that referenced this pull request May 17, 2025
@kleisauke
Copy link
Member Author

You're right. I just pushed commit kleisauke@1f0054e to that branch, since that's probably(?) the only place where it needs to be future-proof.

Note that we sometimes do similar checks elsewhere, for example:

image->BandFmt > VIPS_FORMAT_DPCOMPLEX ||

which is likely safe, I don't expect any new band formats in the near future.

kleisauke added a commit to kleisauke/libvips that referenced this pull request Jun 9, 2025
These `_LAST` enums can be confusing to reference.
jcupitt pushed a commit that referenced this pull request Jun 9, 2025
* Add missing files to 8.17 docs

These were missed in PR #4555.

* Backport PR #4520 to 8.17 docs

These `_LAST` enums can be confusing to reference.

* Fix permalink to old function list
@kleisauke
Copy link
Member Author

This is ready for review. I think removing the _LAST enum members would be too disruptive for now.

@kleisauke kleisauke marked this pull request as ready for review June 27, 2025 11:49
@@ -174,8 +174,8 @@ typedef enum {
* See also: [method@Image.complex2].
*/
typedef enum {
VIPS_OPERATION_COMPLEX2_CROSS_PHASE,
VIPS_OPERATION_COMPLEX2_LAST
VIPS_OPERATION_COMPLEX2_CROSS_PHASE, /*< nick=cross-phase >*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't know you could set nick here, nice!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. Previously, the nickname was derived by stripping common prefix words from all enum values. However, with only one enum value remaining, this would reduce the nickname to just phase. This change prevents that.

@jcupitt jcupitt merged commit a5a0d0a into libvips:master Jun 29, 2025
6 checks passed
@jcupitt
Copy link
Member

jcupitt commented Jun 29, 2025

Great! This is a good cleanup.

@kleisauke kleisauke deleted the enumtypes-remove-last-member branch June 29, 2025 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants