diff --git a/src/scanner.c b/src/scanner.c index a4f3cc96..3cd05d13 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -1391,22 +1391,35 @@ emit_validator(struct interface *interface, struct enumeration *e) " * @ref %s_%s\n" " */\n" "static inline bool\n" - "%s_%s_is_valid(uint32_t value, uint32_t version) {\n" - " switch (value) {\n", + "%s_%s_is_valid(uint32_t value, uint32_t version) {\n", interface->name, interface->name, e->name, interface->name, e->name, interface->name, e->name); - wl_list_for_each(entry, &e->entry_list, link) { - printf(" case %s%s_%s_%s:\n" - " return version >= %d;\n", - entry->value[0] == '-' ? "(uint32_t)" : "", - interface->uppercase_name, e->uppercase_name, - entry->uppercase_name, entry->since); + + if (e->bitfield) { + printf(" uint32_t valid = 0;\n"); + wl_list_for_each(entry, &e->entry_list, link) { + printf(" if (version >= %d)\n" + " valid |= %s_%s_%s;\n", + entry->since, + interface->uppercase_name, e->uppercase_name, + entry->uppercase_name); + } + printf(" return (value & ~valid) == 0;\n"); + } else { + printf(" switch (value) {\n"); + wl_list_for_each(entry, &e->entry_list, link) { + printf(" case %s%s_%s_%s:\n" + " return version >= %d;\n", + entry->value[0] == '-' ? "(uint32_t)" : "", + interface->uppercase_name, e->uppercase_name, + entry->uppercase_name, entry->since); + } + printf(" default:\n" + " return false;\n" + " }\n"); } - printf(" default:\n" - " return false;\n" - " }\n" - "}\n"); + printf("}\n"); } static void diff --git a/tests/data/example-server.h b/tests/data/example-server.h index b0d9226d..2fad7097 100644 --- a/tests/data/example-server.h +++ b/tests/data/example-server.h @@ -2396,18 +2396,16 @@ enum wl_data_device_manager_dnd_action { */ static inline bool wl_data_device_manager_dnd_action_is_valid(uint32_t value, uint32_t version) { - switch (value) { - case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE: - return version >= 1; - case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY: - return version >= 1; - case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE: - return version >= 1; - case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK: - return version >= 1; - default: - return false; - } + uint32_t valid = 0; + if (version >= 1) + valid |= WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; + if (version >= 1) + valid |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; + if (version >= 1) + valid |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; + if (version >= 1) + valid |= WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; + return (value & ~valid) == 0; } #endif /* WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM */ @@ -2560,28 +2558,26 @@ enum wl_shell_surface_resize { */ static inline bool wl_shell_surface_resize_is_valid(uint32_t value, uint32_t version) { - switch (value) { - case WL_SHELL_SURFACE_RESIZE_NONE: - return version >= 1; - case WL_SHELL_SURFACE_RESIZE_TOP: - return version >= 1; - case WL_SHELL_SURFACE_RESIZE_BOTTOM: - return version >= 1; - case WL_SHELL_SURFACE_RESIZE_LEFT: - return version >= 1; - case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: - return version >= 1; - case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT: - return version >= 1; - case WL_SHELL_SURFACE_RESIZE_RIGHT: - return version >= 1; - case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT: - return version >= 1; - case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT: - return version >= 1; - default: - return false; - } + uint32_t valid = 0; + if (version >= 1) + valid |= WL_SHELL_SURFACE_RESIZE_NONE; + if (version >= 1) + valid |= WL_SHELL_SURFACE_RESIZE_TOP; + if (version >= 1) + valid |= WL_SHELL_SURFACE_RESIZE_BOTTOM; + if (version >= 1) + valid |= WL_SHELL_SURFACE_RESIZE_LEFT; + if (version >= 1) + valid |= WL_SHELL_SURFACE_RESIZE_TOP_LEFT; + if (version >= 1) + valid |= WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT; + if (version >= 1) + valid |= WL_SHELL_SURFACE_RESIZE_RIGHT; + if (version >= 1) + valid |= WL_SHELL_SURFACE_RESIZE_TOP_RIGHT; + if (version >= 1) + valid |= WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT; + return (value & ~valid) == 0; } #endif /* WL_SHELL_SURFACE_RESIZE_ENUM */ @@ -2609,12 +2605,10 @@ enum wl_shell_surface_transient { */ static inline bool wl_shell_surface_transient_is_valid(uint32_t value, uint32_t version) { - switch (value) { - case WL_SHELL_SURFACE_TRANSIENT_INACTIVE: - return version >= 1; - default: - return false; - } + uint32_t valid = 0; + if (version >= 1) + valid |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE; + return (value & ~valid) == 0; } #endif /* WL_SHELL_SURFACE_TRANSIENT_ENUM */ @@ -3486,16 +3480,14 @@ enum wl_seat_capability { */ static inline bool wl_seat_capability_is_valid(uint32_t value, uint32_t version) { - switch (value) { - case WL_SEAT_CAPABILITY_POINTER: - return version >= 1; - case WL_SEAT_CAPABILITY_KEYBOARD: - return version >= 1; - case WL_SEAT_CAPABILITY_TOUCH: - return version >= 1; - default: - return false; - } + uint32_t valid = 0; + if (version >= 1) + valid |= WL_SEAT_CAPABILITY_POINTER; + if (version >= 1) + valid |= WL_SEAT_CAPABILITY_KEYBOARD; + if (version >= 1) + valid |= WL_SEAT_CAPABILITY_TOUCH; + return (value & ~valid) == 0; } #endif /* WL_SEAT_CAPABILITY_ENUM */ @@ -4567,14 +4559,12 @@ enum wl_output_mode { */ static inline bool wl_output_mode_is_valid(uint32_t value, uint32_t version) { - switch (value) { - case WL_OUTPUT_MODE_CURRENT: - return version >= 1; - case WL_OUTPUT_MODE_PREFERRED: - return version >= 1; - default: - return false; - } + uint32_t valid = 0; + if (version >= 1) + valid |= WL_OUTPUT_MODE_CURRENT; + if (version >= 1) + valid |= WL_OUTPUT_MODE_PREFERRED; + return (value & ~valid) == 0; } #endif /* WL_OUTPUT_MODE_ENUM */