summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2022-09-17 10:53:56 +0200
committerSimon Ser <contact@emersion.fr>2024-04-23 09:17:02 +0000
commitb258d5f36137088e5cb5ae097db7964290da7d55 (patch)
tree2f59d6061156e64e8c5797942fe4818ab69529be
parent5eeaac6e1114fddeb36682ef1eead967c06e9b02 (diff)
scanner: add validators for enums
Right now compositors need to manually check that enum values sent by the client are valid. In particular: - Check that the value sent by the client is not outside of the enum. - Check that the version of the enum entry is consistent with the object version. Automatically generate validator functions to perform these tasks. Signed-off-by: Simon Ser <contact@emersion.fr> Closes: https://gitlab.freedesktop.org/wayland/wayland/-/issues/104
-rw-r--r--src/scanner.c36
-rw-r--r--tests/data/empty-code.c1
-rw-r--r--tests/data/example-code.c1
-rw-r--r--tests/data/example-server.h588
-rw-r--r--tests/data/small-client-core.h9
-rw-r--r--tests/data/small-client.h9
-rw-r--r--tests/data/small-code-core.c1
-rw-r--r--tests/data/small-code.c1
-rw-r--r--tests/data/small-private-code.c1
-rw-r--r--tests/data/small-server-core.h31
-rw-r--r--tests/data/small-server.h31
-rw-r--r--tests/data/small.xml1
-rw-r--r--tests/enum-validator-test.c13
-rw-r--r--tests/meson.build1
14 files changed, 720 insertions, 4 deletions
diff --git a/src/scanner.c b/src/scanner.c
index 3257cb6..3f528f3 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -1344,7 +1344,7 @@ emit_event_wrappers(struct wl_list *message_list, struct interface *interface)
}
static void
-emit_enumerations(struct interface *interface)
+emit_enumerations(struct interface *interface, bool with_validators)
{
struct enumeration *e;
struct entry *entry;
@@ -1401,6 +1401,33 @@ emit_enumerations(struct interface *interface)
}
+ if (with_validators) {
+ printf("/**\n"
+ " * @ingroup iface_%s\n"
+ " * Validate a %s %s value.\n"
+ " *\n"
+ " * @return true on success, false on error.\n"
+ " * @ref %s_%s\n"
+ " */\n"
+ "static inline bool\n"
+ "%s_%s_is_valid(uint32_t value, uint32_t version) {\n"
+ " switch (value) {\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);
+ }
+ printf(" default:\n"
+ " return false;\n"
+ " }\n"
+ "}\n");
+ }
+
printf("#endif /* %s_%s_ENUM */\n\n",
interface->uppercase_name, e->uppercase_name);
}
@@ -1677,7 +1704,7 @@ emit_header(struct protocol *protocol, enum side side)
wl_list_for_each_safe(i, i_next, &protocol->interface_list, link) {
- emit_enumerations(i);
+ emit_enumerations(i, side == SERVER);
if (side == SERVER) {
emit_structs(&i->request_list, i, side);
@@ -1720,7 +1747,7 @@ emit_enum_header(struct protocol *protocol)
protocol->uppercase_name);
wl_list_for_each_safe(i, i_next, &protocol->interface_list, link) {
- emit_enumerations(i);
+ emit_enumerations(i, false);
free_interface(i);
}
@@ -1849,7 +1876,8 @@ emit_code(struct protocol *protocol, enum visibility vis)
if (protocol->copyright)
format_text_to_comment(protocol->copyright, true);
- printf("#include <stdlib.h>\n"
+ printf("#include <stdbool.h>\n"
+ "#include <stdlib.h>\n"
"#include <stdint.h>\n"
"#include \"wayland-util.h\"\n\n");
diff --git a/tests/data/empty-code.c b/tests/data/empty-code.c
index 6f0f619..67382d2 100644
--- a/tests/data/empty-code.c
+++ b/tests/data/empty-code.c
@@ -1,5 +1,6 @@
/* SCANNER TEST */
+#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
diff --git a/tests/data/example-code.c b/tests/data/example-code.c
index 2055c88..37feed7 100644
--- a/tests/data/example-code.c
+++ b/tests/data/example-code.c
@@ -27,6 +27,7 @@
* SOFTWARE.
*/
+#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
diff --git a/tests/data/example-server.h b/tests/data/example-server.h
index 7cfa4e7..b0d9226 100644
--- a/tests/data/example-server.h
+++ b/tests/data/example-server.h
@@ -901,6 +901,26 @@ enum wl_display_error {
*/
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
+/**
+ * @ingroup iface_wl_display
+ * Validate a wl_display error value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_display_error
+ */
+static inline bool
+wl_display_error_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_DISPLAY_ERROR_INVALID_OBJECT:
+ return version >= 1;
+ case WL_DISPLAY_ERROR_INVALID_METHOD:
+ return version >= 1;
+ case WL_DISPLAY_ERROR_NO_MEMORY:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_DISPLAY_ERROR_ENUM */
/**
@@ -1174,6 +1194,26 @@ enum wl_shm_error {
*/
WL_SHM_ERROR_INVALID_FD = 2,
};
+/**
+ * @ingroup iface_wl_shm
+ * Validate a wl_shm error value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_shm_error
+ */
+static inline bool
+wl_shm_error_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_SHM_ERROR_INVALID_FORMAT:
+ return version >= 1;
+ case WL_SHM_ERROR_INVALID_STRIDE:
+ return version >= 1;
+ case WL_SHM_ERROR_INVALID_FD:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_SHM_ERROR_ENUM */
#ifndef WL_SHM_FORMAT_ENUM
@@ -1426,6 +1466,136 @@ enum wl_shm_format {
*/
WL_SHM_FORMAT_YVU444 = 0x34325659,
};
+/**
+ * @ingroup iface_wl_shm
+ * Validate a wl_shm format value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_shm_format
+ */
+static inline bool
+wl_shm_format_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_SHM_FORMAT_ARGB8888:
+ return version >= 1;
+ case WL_SHM_FORMAT_XRGB8888:
+ return version >= 1;
+ case WL_SHM_FORMAT_C8:
+ return version >= 1;
+ case WL_SHM_FORMAT_RGB332:
+ return version >= 1;
+ case WL_SHM_FORMAT_BGR233:
+ return version >= 1;
+ case WL_SHM_FORMAT_XRGB4444:
+ return version >= 1;
+ case WL_SHM_FORMAT_XBGR4444:
+ return version >= 1;
+ case WL_SHM_FORMAT_RGBX4444:
+ return version >= 1;
+ case WL_SHM_FORMAT_BGRX4444:
+ return version >= 1;
+ case WL_SHM_FORMAT_ARGB4444:
+ return version >= 1;
+ case WL_SHM_FORMAT_ABGR4444:
+ return version >= 1;
+ case WL_SHM_FORMAT_RGBA4444:
+ return version >= 1;
+ case WL_SHM_FORMAT_BGRA4444:
+ return version >= 1;
+ case WL_SHM_FORMAT_XRGB1555:
+ return version >= 1;
+ case WL_SHM_FORMAT_XBGR1555:
+ return version >= 1;
+ case WL_SHM_FORMAT_RGBX5551:
+ return version >= 1;
+ case WL_SHM_FORMAT_BGRX5551:
+ return version >= 1;
+ case WL_SHM_FORMAT_ARGB1555:
+ return version >= 1;
+ case WL_SHM_FORMAT_ABGR1555:
+ return version >= 1;
+ case WL_SHM_FORMAT_RGBA5551:
+ return version >= 1;
+ case WL_SHM_FORMAT_BGRA5551:
+ return version >= 1;
+ case WL_SHM_FORMAT_RGB565:
+ return version >= 1;
+ case WL_SHM_FORMAT_BGR565:
+ return version >= 1;
+ case WL_SHM_FORMAT_RGB888:
+ return version >= 1;
+ case WL_SHM_FORMAT_BGR888:
+ return version >= 1;
+ case WL_SHM_FORMAT_XBGR8888:
+ return version >= 1;
+ case WL_SHM_FORMAT_RGBX8888:
+ return version >= 1;
+ case WL_SHM_FORMAT_BGRX8888:
+ return version >= 1;
+ case WL_SHM_FORMAT_ABGR8888:
+ return version >= 1;
+ case WL_SHM_FORMAT_RGBA8888:
+ return version >= 1;
+ case WL_SHM_FORMAT_BGRA8888:
+ return version >= 1;
+ case WL_SHM_FORMAT_XRGB2101010:
+ return version >= 1;
+ case WL_SHM_FORMAT_XBGR2101010:
+ return version >= 1;
+ case WL_SHM_FORMAT_RGBX1010102:
+ return version >= 1;
+ case WL_SHM_FORMAT_BGRX1010102:
+ return version >= 1;
+ case WL_SHM_FORMAT_ARGB2101010:
+ return version >= 1;
+ case WL_SHM_FORMAT_ABGR2101010:
+ return version >= 1;
+ case WL_SHM_FORMAT_RGBA1010102:
+ return version >= 1;
+ case WL_SHM_FORMAT_BGRA1010102:
+ return version >= 1;
+ case WL_SHM_FORMAT_YUYV:
+ return version >= 1;
+ case WL_SHM_FORMAT_YVYU:
+ return version >= 1;
+ case WL_SHM_FORMAT_UYVY:
+ return version >= 1;
+ case WL_SHM_FORMAT_VYUY:
+ return version >= 1;
+ case WL_SHM_FORMAT_AYUV:
+ return version >= 1;
+ case WL_SHM_FORMAT_NV12:
+ return version >= 1;
+ case WL_SHM_FORMAT_NV21:
+ return version >= 1;
+ case WL_SHM_FORMAT_NV16:
+ return version >= 1;
+ case WL_SHM_FORMAT_NV61:
+ return version >= 1;
+ case WL_SHM_FORMAT_YUV410:
+ return version >= 1;
+ case WL_SHM_FORMAT_YVU410:
+ return version >= 1;
+ case WL_SHM_FORMAT_YUV411:
+ return version >= 1;
+ case WL_SHM_FORMAT_YVU411:
+ return version >= 1;
+ case WL_SHM_FORMAT_YUV420:
+ return version >= 1;
+ case WL_SHM_FORMAT_YVU420:
+ return version >= 1;
+ case WL_SHM_FORMAT_YUV422:
+ return version >= 1;
+ case WL_SHM_FORMAT_YVU422:
+ return version >= 1;
+ case WL_SHM_FORMAT_YUV444:
+ return version >= 1;
+ case WL_SHM_FORMAT_YVU444:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_SHM_FORMAT_ENUM */
/**
@@ -1536,6 +1706,28 @@ enum wl_data_offer_error {
*/
WL_DATA_OFFER_ERROR_INVALID_OFFER = 3,
};
+/**
+ * @ingroup iface_wl_data_offer
+ * Validate a wl_data_offer error value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_data_offer_error
+ */
+static inline bool
+wl_data_offer_error_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_DATA_OFFER_ERROR_INVALID_FINISH:
+ return version >= 1;
+ case WL_DATA_OFFER_ERROR_INVALID_ACTION_MASK:
+ return version >= 1;
+ case WL_DATA_OFFER_ERROR_INVALID_ACTION:
+ return version >= 1;
+ case WL_DATA_OFFER_ERROR_INVALID_OFFER:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_DATA_OFFER_ERROR_ENUM */
/**
@@ -1748,6 +1940,24 @@ enum wl_data_source_error {
*/
WL_DATA_SOURCE_ERROR_INVALID_SOURCE = 1,
};
+/**
+ * @ingroup iface_wl_data_source
+ * Validate a wl_data_source error value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_data_source_error
+ */
+static inline bool
+wl_data_source_error_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_DATA_SOURCE_ERROR_INVALID_ACTION_MASK:
+ return version >= 1;
+ case WL_DATA_SOURCE_ERROR_INVALID_SOURCE:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_DATA_SOURCE_ERROR_ENUM */
/**
@@ -1920,6 +2130,22 @@ enum wl_data_device_error {
*/
WL_DATA_DEVICE_ERROR_ROLE = 0,
};
+/**
+ * @ingroup iface_wl_data_device
+ * Validate a wl_data_device error value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_data_device_error
+ */
+static inline bool
+wl_data_device_error_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_DATA_DEVICE_ERROR_ROLE:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_DATA_DEVICE_ERROR_ENUM */
/**
@@ -2161,6 +2387,28 @@ enum wl_data_device_manager_dnd_action {
*/
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK = 4,
};
+/**
+ * @ingroup iface_wl_data_device_manager
+ * Validate a wl_data_device_manager dnd_action value.
+ *
+ * @return true on success, false on error.
+ * @ref 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;
+ }
+}
#endif /* WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM */
/**
@@ -2208,6 +2456,22 @@ enum wl_shell_error {
*/
WL_SHELL_ERROR_ROLE = 0,
};
+/**
+ * @ingroup iface_wl_shell
+ * Validate a wl_shell error value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_shell_error
+ */
+static inline bool
+wl_shell_error_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_SHELL_ERROR_ROLE:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_SHELL_ERROR_ENUM */
/**
@@ -2287,6 +2551,38 @@ enum wl_shell_surface_resize {
*/
WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT = 10,
};
+/**
+ * @ingroup iface_wl_shell_surface
+ * Validate a wl_shell_surface resize value.
+ *
+ * @return true on success, false on error.
+ * @ref 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;
+ }
+}
#endif /* WL_SHELL_SURFACE_RESIZE_ENUM */
#ifndef WL_SHELL_SURFACE_TRANSIENT_ENUM
@@ -2304,6 +2600,22 @@ enum wl_shell_surface_transient {
*/
WL_SHELL_SURFACE_TRANSIENT_INACTIVE = 0x1,
};
+/**
+ * @ingroup iface_wl_shell_surface
+ * Validate a wl_shell_surface transient value.
+ *
+ * @return true on success, false on error.
+ * @ref 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;
+ }
+}
#endif /* WL_SHELL_SURFACE_TRANSIENT_ENUM */
#ifndef WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM
@@ -2334,6 +2646,28 @@ enum wl_shell_surface_fullscreen_method {
*/
WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL = 3,
};
+/**
+ * @ingroup iface_wl_shell_surface
+ * Validate a wl_shell_surface fullscreen_method value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_shell_surface_fullscreen_method
+ */
+static inline bool
+wl_shell_surface_fullscreen_method_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT:
+ return version >= 1;
+ case WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE:
+ return version >= 1;
+ case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER:
+ return version >= 1;
+ case WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM */
/**
@@ -2666,6 +3000,24 @@ enum wl_surface_error {
*/
WL_SURFACE_ERROR_INVALID_TRANSFORM = 1,
};
+/**
+ * @ingroup iface_wl_surface
+ * Validate a wl_surface error value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_surface_error
+ */
+static inline bool
+wl_surface_error_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_SURFACE_ERROR_INVALID_SCALE:
+ return version >= 1;
+ case WL_SURFACE_ERROR_INVALID_TRANSFORM:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_SURFACE_ERROR_ENUM */
/**
@@ -3125,6 +3477,26 @@ enum wl_seat_capability {
*/
WL_SEAT_CAPABILITY_TOUCH = 4,
};
+/**
+ * @ingroup iface_wl_seat
+ * Validate a wl_seat capability value.
+ *
+ * @return true on success, false on error.
+ * @ref 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;
+ }
+}
#endif /* WL_SEAT_CAPABILITY_ENUM */
/**
@@ -3249,6 +3621,22 @@ enum wl_pointer_error {
*/
WL_POINTER_ERROR_ROLE = 0,
};
+/**
+ * @ingroup iface_wl_pointer
+ * Validate a wl_pointer error value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_pointer_error
+ */
+static inline bool
+wl_pointer_error_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_POINTER_ERROR_ROLE:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_POINTER_ERROR_ENUM */
#ifndef WL_POINTER_BUTTON_STATE_ENUM
@@ -3270,6 +3658,24 @@ enum wl_pointer_button_state {
*/
WL_POINTER_BUTTON_STATE_PRESSED = 1,
};
+/**
+ * @ingroup iface_wl_pointer
+ * Validate a wl_pointer button_state value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_pointer_button_state
+ */
+static inline bool
+wl_pointer_button_state_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_POINTER_BUTTON_STATE_RELEASED:
+ return version >= 1;
+ case WL_POINTER_BUTTON_STATE_PRESSED:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_POINTER_BUTTON_STATE_ENUM */
#ifndef WL_POINTER_AXIS_ENUM
@@ -3290,6 +3696,24 @@ enum wl_pointer_axis {
*/
WL_POINTER_AXIS_HORIZONTAL_SCROLL = 1,
};
+/**
+ * @ingroup iface_wl_pointer
+ * Validate a wl_pointer axis value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_pointer_axis
+ */
+static inline bool
+wl_pointer_axis_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_POINTER_AXIS_VERTICAL_SCROLL:
+ return version >= 1;
+ case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_POINTER_AXIS_ENUM */
#ifndef WL_POINTER_AXIS_SOURCE_ENUM
@@ -3338,6 +3762,28 @@ enum wl_pointer_axis_source {
* @ingroup iface_wl_pointer
*/
#define WL_POINTER_AXIS_SOURCE_WHEEL_TILT_SINCE_VERSION 6
+/**
+ * @ingroup iface_wl_pointer
+ * Validate a wl_pointer axis_source value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_pointer_axis_source
+ */
+static inline bool
+wl_pointer_axis_source_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_POINTER_AXIS_SOURCE_WHEEL:
+ return version >= 1;
+ case WL_POINTER_AXIS_SOURCE_FINGER:
+ return version >= 1;
+ case WL_POINTER_AXIS_SOURCE_CONTINUOUS:
+ return version >= 1;
+ case WL_POINTER_AXIS_SOURCE_WHEEL_TILT:
+ return version >= 6;
+ default:
+ return false;
+ }
+}
#endif /* WL_POINTER_AXIS_SOURCE_ENUM */
/**
@@ -3599,6 +4045,24 @@ enum wl_keyboard_keymap_format {
*/
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 = 1,
};
+/**
+ * @ingroup iface_wl_keyboard
+ * Validate a wl_keyboard keymap_format value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_keyboard_keymap_format
+ */
+static inline bool
+wl_keyboard_keymap_format_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP:
+ return version >= 1;
+ case WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_KEYBOARD_KEYMAP_FORMAT_ENUM */
#ifndef WL_KEYBOARD_KEY_STATE_ENUM
@@ -3619,6 +4083,24 @@ enum wl_keyboard_key_state {
*/
WL_KEYBOARD_KEY_STATE_PRESSED = 1,
};
+/**
+ * @ingroup iface_wl_keyboard
+ * Validate a wl_keyboard key_state value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_keyboard_key_state
+ */
+static inline bool
+wl_keyboard_key_state_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_KEYBOARD_KEY_STATE_RELEASED:
+ return version >= 1;
+ case WL_KEYBOARD_KEY_STATE_PRESSED:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_KEYBOARD_KEY_STATE_ENUM */
/**
@@ -3945,6 +4427,32 @@ enum wl_output_subpixel {
*/
WL_OUTPUT_SUBPIXEL_VERTICAL_BGR = 5,
};
+/**
+ * @ingroup iface_wl_output
+ * Validate a wl_output subpixel value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_output_subpixel
+ */
+static inline bool
+wl_output_subpixel_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_OUTPUT_SUBPIXEL_UNKNOWN:
+ return version >= 1;
+ case WL_OUTPUT_SUBPIXEL_NONE:
+ return version >= 1;
+ case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
+ return version >= 1;
+ case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
+ return version >= 1;
+ case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
+ return version >= 1;
+ case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_OUTPUT_SUBPIXEL_ENUM */
#ifndef WL_OUTPUT_TRANSFORM_ENUM
@@ -3999,6 +4507,36 @@ enum wl_output_transform {
*/
WL_OUTPUT_TRANSFORM_FLIPPED_270 = 7,
};
+/**
+ * @ingroup iface_wl_output
+ * Validate a wl_output transform value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_output_transform
+ */
+static inline bool
+wl_output_transform_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_OUTPUT_TRANSFORM_NORMAL:
+ return version >= 1;
+ case WL_OUTPUT_TRANSFORM_90:
+ return version >= 1;
+ case WL_OUTPUT_TRANSFORM_180:
+ return version >= 1;
+ case WL_OUTPUT_TRANSFORM_270:
+ return version >= 1;
+ case WL_OUTPUT_TRANSFORM_FLIPPED:
+ return version >= 1;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ return version >= 1;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+ return version >= 1;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_OUTPUT_TRANSFORM_ENUM */
#ifndef WL_OUTPUT_MODE_ENUM
@@ -4020,6 +4558,24 @@ enum wl_output_mode {
*/
WL_OUTPUT_MODE_PREFERRED = 0x2,
};
+/**
+ * @ingroup iface_wl_output
+ * Validate a wl_output mode value.
+ *
+ * @return true on success, false on error.
+ * @ref 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;
+ }
+}
#endif /* WL_OUTPUT_MODE_ENUM */
/**
@@ -4188,6 +4744,22 @@ enum wl_subcompositor_error {
*/
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE = 0,
};
+/**
+ * @ingroup iface_wl_subcompositor
+ * Validate a wl_subcompositor error value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_subcompositor_error
+ */
+static inline bool
+wl_subcompositor_error_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_SUBCOMPOSITOR_ERROR_ENUM */
/**
@@ -4243,6 +4815,22 @@ enum wl_subsurface_error {
*/
WL_SUBSURFACE_ERROR_BAD_SURFACE = 0,
};
+/**
+ * @ingroup iface_wl_subsurface
+ * Validate a wl_subsurface error value.
+ *
+ * @return true on success, false on error.
+ * @ref wl_subsurface_error
+ */
+static inline bool
+wl_subsurface_error_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case WL_SUBSURFACE_ERROR_BAD_SURFACE:
+ return version >= 1;
+ default:
+ return false;
+ }
+}
#endif /* WL_SUBSURFACE_ERROR_ENUM */
/**
diff --git a/tests/data/small-client-core.h b/tests/data/small-client-core.h
index 348d2dc..e5e2193 100644
--- a/tests/data/small-client-core.h
+++ b/tests/data/small-client-core.h
@@ -80,11 +80,20 @@ enum intf_A_foo {
* @since 2
*/
INTF_A_FOO_THIRD = 2,
+ /**
+ * this is a negative value
+ * @since 2
+ */
+ INTF_A_FOO_NEGATIVE = -1,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_FOO_THIRD_SINCE_VERSION 2
+/**
+ * @ingroup iface_intf_A
+ */
+#define INTF_A_FOO_NEGATIVE_SINCE_VERSION 2
#endif /* INTF_A_FOO_ENUM */
/**
diff --git a/tests/data/small-client.h b/tests/data/small-client.h
index 8c6abc5..c81b70f 100644
--- a/tests/data/small-client.h
+++ b/tests/data/small-client.h
@@ -80,11 +80,20 @@ enum intf_A_foo {
* @since 2
*/
INTF_A_FOO_THIRD = 2,
+ /**
+ * this is a negative value
+ * @since 2
+ */
+ INTF_A_FOO_NEGATIVE = -1,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_FOO_THIRD_SINCE_VERSION 2
+/**
+ * @ingroup iface_intf_A
+ */
+#define INTF_A_FOO_NEGATIVE_SINCE_VERSION 2
#endif /* INTF_A_FOO_ENUM */
/**
diff --git a/tests/data/small-code-core.c b/tests/data/small-code-core.c
index bd6d33d..88e8257 100644
--- a/tests/data/small-code-core.c
+++ b/tests/data/small-code-core.c
@@ -25,6 +25,7 @@
* SOFTWARE.
*/
+#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
diff --git a/tests/data/small-code.c b/tests/data/small-code.c
index bd6d33d..88e8257 100644
--- a/tests/data/small-code.c
+++ b/tests/data/small-code.c
@@ -25,6 +25,7 @@
* SOFTWARE.
*/
+#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
diff --git a/tests/data/small-private-code.c b/tests/data/small-private-code.c
index fe035ff..1679431 100644
--- a/tests/data/small-private-code.c
+++ b/tests/data/small-private-code.c
@@ -25,6 +25,7 @@
* SOFTWARE.
*/
+#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
diff --git a/tests/data/small-server-core.h b/tests/data/small-server-core.h
index f0fd1f9..ff19d67 100644
--- a/tests/data/small-server-core.h
+++ b/tests/data/small-server-core.h
@@ -83,11 +83,42 @@ enum intf_A_foo {
* @since 2
*/
INTF_A_FOO_THIRD = 2,
+ /**
+ * this is a negative value
+ * @since 2
+ */
+ INTF_A_FOO_NEGATIVE = -1,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_FOO_THIRD_SINCE_VERSION 2
+/**
+ * @ingroup iface_intf_A
+ */
+#define INTF_A_FOO_NEGATIVE_SINCE_VERSION 2
+/**
+ * @ingroup iface_intf_A
+ * Validate a intf_A foo value.
+ *
+ * @return true on success, false on error.
+ * @ref intf_A_foo
+ */
+static inline bool
+intf_A_foo_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case INTF_A_FOO_FIRST:
+ return version >= 1;
+ case INTF_A_FOO_SECOND:
+ return version >= 1;
+ case INTF_A_FOO_THIRD:
+ return version >= 2;
+ case (uint32_t)INTF_A_FOO_NEGATIVE:
+ return version >= 2;
+ default:
+ return false;
+ }
+}
#endif /* INTF_A_FOO_ENUM */
/**
diff --git a/tests/data/small-server.h b/tests/data/small-server.h
index 22b8113..13fd1ed 100644
--- a/tests/data/small-server.h
+++ b/tests/data/small-server.h
@@ -83,11 +83,42 @@ enum intf_A_foo {
* @since 2
*/
INTF_A_FOO_THIRD = 2,
+ /**
+ * this is a negative value
+ * @since 2
+ */
+ INTF_A_FOO_NEGATIVE = -1,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_FOO_THIRD_SINCE_VERSION 2
+/**
+ * @ingroup iface_intf_A
+ */
+#define INTF_A_FOO_NEGATIVE_SINCE_VERSION 2
+/**
+ * @ingroup iface_intf_A
+ * Validate a intf_A foo value.
+ *
+ * @return true on success, false on error.
+ * @ref intf_A_foo
+ */
+static inline bool
+intf_A_foo_is_valid(uint32_t value, uint32_t version) {
+ switch (value) {
+ case INTF_A_FOO_FIRST:
+ return version >= 1;
+ case INTF_A_FOO_SECOND:
+ return version >= 1;
+ case INTF_A_FOO_THIRD:
+ return version >= 2;
+ case (uint32_t)INTF_A_FOO_NEGATIVE:
+ return version >= 2;
+ default:
+ return false;
+ }
+}
#endif /* INTF_A_FOO_ENUM */
/**
diff --git a/tests/data/small.xml b/tests/data/small.xml
index 832ed0e..685c891 100644
--- a/tests/data/small.xml
+++ b/tests/data/small.xml
@@ -53,6 +53,7 @@
<entry name="first" value="0" summary="this is the first"/>
<entry name="second" value="1" summary="this is the second"/>
<entry name="third" value="2" since="2" summary="this is the third"/>
+ <entry name="negative" value="-1" since="2" summary="this is a negative value"/>
</enum>
</interface>
</protocol>
diff --git a/tests/enum-validator-test.c b/tests/enum-validator-test.c
new file mode 100644
index 0000000..92037cf
--- /dev/null
+++ b/tests/enum-validator-test.c
@@ -0,0 +1,13 @@
+#include <assert.h>
+#include "data/small-server-core.h"
+
+int
+main(int argc, char *argv[]) {
+ assert(intf_A_foo_is_valid(INTF_A_FOO_FIRST, 1));
+ assert(intf_A_foo_is_valid(INTF_A_FOO_FIRST, 2));
+
+ assert(!intf_A_foo_is_valid(INTF_A_FOO_THIRD, 1));
+ assert(intf_A_foo_is_valid(INTF_A_FOO_THIRD, 2));
+
+ assert(intf_A_foo_is_valid(INTF_A_FOO_NEGATIVE, 2));
+}
diff --git a/tests/meson.build b/tests/meson.build
index 236f08c..2c22b82 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -158,6 +158,7 @@ tests = {
wayland_client_protocol_h,
wayland_server_protocol_h,
],
+ 'enum-validator-test': [],
}
foreach test_name, test_extra_sources: tests