From 37bd43511b917a50fdab4a4d83a3e75dd70935c9 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 Mar 2016 14:29:56 +1000 Subject: [PATCH] Switch to using an emum for error codes Whenever we do something that may fail, return an enum of possible errors. This also changes the API for ratbag_device_new_from_udev_device() to return an error code now too instead of just NULL on failure. Error numbers start at -1000 to avoid overlap with errnos, error_code() should be used internally to avoid returning an errno. Signed-off-by: Peter Hutterer --- src/libratbag.c | 131 ++++++++++++++++++++++++++++------------------ src/libratbag.h | 104 ++++++++++++++++++++++++++---------- src/libratbag.sym | 2 +- tools/shared.c | 6 ++- 4 files changed, 162 insertions(+), 81 deletions(-) diff --git a/src/libratbag.c b/src/libratbag.c index 8baa9e9d..94a7d10c 100644 --- a/src/libratbag.c +++ b/src/libratbag.c @@ -37,6 +37,23 @@ #include "libratbag-private.h" #include "libratbag-util.h" +static enum ratbag_error_code +error_code(enum ratbag_error_code code) +{ + switch(code) { + case RATBAG_SUCCESS: + case RATBAG_ERROR_DEVICE: + case RATBAG_ERROR_CAPABILITY: + case RATBAG_ERROR_VALUE: + case RATBAG_ERROR_SYSTEM: + case RATBAG_ERROR_IMPLEMENTATION: + break; + default: + assert(!"Invalid error code. This is a library bug."); + } + return code; +} + static void ratbag_profile_destroy(struct ratbag_profile *profile); static void @@ -353,43 +370,46 @@ get_product_id(struct udev_device *device, struct input_id *id) return 0; } -LIBRATBAG_EXPORT struct ratbag_device* +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_device_new_from_udev_device(struct ratbag *ratbag, - struct udev_device *udev_device) + struct udev_device *udev_device, + struct ratbag_device **device_out) { struct ratbag_device *device = NULL; struct ratbag_driver *driver; + enum ratbag_error_code error = RATBAG_ERROR_DEVICE; _cleanup_free_ char *name = NULL; struct input_id id; assert(ratbag != NULL); assert(udev_device != NULL); + assert(device_out != NULL); if (get_product_id(udev_device, &id) != 0) goto out_err; name = get_device_name(udev_device); - if (!name) { - errno = ENOMEM; + if (!name) goto out_err; - } device = ratbag_device_new(ratbag, udev_device, name, &id); if (!device) goto out_err; driver = ratbag_find_driver(device, &device->ids, NULL); - if (!driver) { - errno = ENOTSUP; + if (!driver) goto out_err; - } - return device; + error = RATBAG_SUCCESS; out_err: - ratbag_device_destroy(device); - return NULL; + if (error != RATBAG_SUCCESS) + ratbag_device_destroy(device); + else + *device_out = device; + + return error_code(error); } LIBRATBAG_EXPORT struct ratbag_device * @@ -693,31 +713,31 @@ ratbag_device_has_capability(const struct ratbag_device *device, return !!(device->capabilities & (1UL << cap)); } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_profile_set_active(struct ratbag_profile *profile) { struct ratbag_device *device = profile->device; struct ratbag_profile *p; int rc; + if (!ratbag_device_has_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE)) + return RATBAG_ERROR_CAPABILITY; + assert(device->driver->write_profile); rc = device->driver->write_profile(profile); if (rc) - return rc; - - if (ratbag_device_has_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE)) { - assert(device->driver->set_active_profile); - rc = device->driver->set_active_profile(device, profile->index); - } + return RATBAG_ERROR_DEVICE; + assert(device->driver->set_active_profile); + rc = device->driver->set_active_profile(device, profile->index); if (rc) - return rc; + return RATBAG_ERROR_DEVICE; list_for_each(p, &device->profiles, link) p->is_active = false; profile->is_active = true; - return rc; + return RATBAG_SUCCESS; } LIBRATBAG_EXPORT unsigned int @@ -782,42 +802,48 @@ ratbag_resolution_has_capability(struct ratbag_resolution *resolution, return !!(resolution->capabilities & (1 << cap)); } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_resolution_set_dpi(struct ratbag_resolution *resolution, unsigned int dpi) { struct ratbag_profile *profile = resolution->profile; + int rc; + resolution->dpi_x = dpi; resolution->dpi_y = dpi; assert(profile->device->driver->write_resolution_dpi); - return profile->device->driver->write_resolution_dpi(resolution, dpi, dpi); + rc = profile->device->driver->write_resolution_dpi(resolution, dpi, dpi); + + return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE; } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_resolution_set_dpi_xy(struct ratbag_resolution *resolution, unsigned int x, unsigned int y) { struct ratbag_profile *profile = resolution->profile; + int rc; if (!ratbag_resolution_has_capability(resolution, RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION)) - return -1; + return RATBAG_ERROR_CAPABILITY; if ((x == 0 && y != 0) || (x != 0 && y == 0)) - return -1; + return RATBAG_ERROR_VALUE; assert(profile->device->driver->write_resolution_dpi); - return profile->device->driver->write_resolution_dpi(resolution, x, y); + rc = profile->device->driver->write_resolution_dpi(resolution, x, y); + return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE; } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution, unsigned int hz) { resolution->hz = hz; /* FIXME: call into the driver */ - return 0; + return RATBAG_ERROR_IMPLEMENTATION; } LIBRATBAG_EXPORT int @@ -850,12 +876,12 @@ ratbag_resolution_is_active(const struct ratbag_resolution *resolution) return resolution->is_active; } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_resolution_set_active(struct ratbag_resolution *resolution) { resolution->is_active = true; /* FIXME: call into the driver */ - return 0; + return RATBAG_ERROR_IMPLEMENTATION; } @@ -865,12 +891,12 @@ ratbag_resolution_is_default(const struct ratbag_resolution *resolution) return resolution->is_default; } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_resolution_set_default(struct ratbag_resolution *resolution) { resolution->is_default = true; /* FIXME: call into the driver */ - return 0; + return RATBAG_ERROR_IMPLEMENTATION; } LIBRATBAG_EXPORT struct ratbag_button* @@ -934,14 +960,14 @@ ratbag_button_get_button(struct ratbag_button *button) return button->action.action.button; } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_button_set_button(struct ratbag_button *button, unsigned int btn) { struct ratbag_button_action action; int rc; if (!button->profile->device->driver->write_button) - return -ENOTSUP; + return RATBAG_ERROR_CAPABILITY; action.type = RATBAG_BUTTON_ACTION_TYPE_BUTTON; action.action.button = btn; @@ -951,7 +977,7 @@ ratbag_button_set_button(struct ratbag_button *button, unsigned int btn) if (rc == 0) button->action = action; - return rc; + return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE; } LIBRATBAG_EXPORT enum ratbag_button_action_special @@ -963,7 +989,7 @@ ratbag_button_get_special(struct ratbag_button *button) return button->action.action.special; } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_button_set_special(struct ratbag_button *button, enum ratbag_button_action_special act) { @@ -973,7 +999,7 @@ ratbag_button_set_special(struct ratbag_button *button, /* FIXME: range checks */ if (!button->profile->device->driver->write_button) - return -1; + return RATBAG_ERROR_CAPABILITY; action.type = RATBAG_BUTTON_ACTION_TYPE_SPECIAL; action.action.special = act; @@ -983,7 +1009,7 @@ ratbag_button_set_special(struct ratbag_button *button, if (rc == 0) button->action = action; - return rc; + return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE; } LIBRATBAG_EXPORT unsigned int @@ -999,7 +1025,7 @@ ratbag_button_get_key(struct ratbag_button *button, return button->action.action.key.key; } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_button_set_key(struct ratbag_button *button, unsigned int key, unsigned int *modifiers, @@ -1011,7 +1037,7 @@ ratbag_button_set_key(struct ratbag_button *button, /* FIXME: range checks */ if (!button->profile->device->driver->write_button) - return -1; + return RATBAG_ERROR_CAPABILITY; /* FIXME: modifiers */ @@ -1022,17 +1048,17 @@ ratbag_button_set_key(struct ratbag_button *button, if (rc == 0) button->action = action; - return rc; + return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE; } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_button_disable(struct ratbag_button *button) { struct ratbag_button_action action; int rc; if (!button->profile->device->driver->write_button) - return -1; + return RATBAG_ERROR_CAPABILITY; action.type = RATBAG_BUTTON_ACTION_TYPE_NONE; rc = button->profile->device->driver->write_button(button, &action); @@ -1040,7 +1066,7 @@ ratbag_button_disable(struct ratbag_button *button) if (rc == 0) button->action = action; - return rc; + return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE; } LIBRATBAG_EXPORT struct ratbag_button * @@ -1139,7 +1165,7 @@ ratbag_resolution_get_user_data(const struct ratbag_resolution *ratbag_resolutio return ratbag_resolution->userdata; } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_button_set_macro(struct ratbag_button *button, const char *name) { if (!button->action.macro) @@ -1153,10 +1179,10 @@ ratbag_button_set_macro(struct ratbag_button *button, const char *name) button->action.type = RATBAG_BUTTON_ACTION_TYPE_MACRO; button->action.macro->name = strdup_safe(name); - return 0; + return RATBAG_SUCCESS; } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_button_set_macro_event(struct ratbag_button *button, unsigned int index, enum ratbag_macro_event_type type, @@ -1166,7 +1192,7 @@ ratbag_button_set_macro_event(struct ratbag_button *button, if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_MACRO || index >= MAX_MACRO_EVENTS) - return -EINVAL; + return RATBAG_ERROR_VALUE; macro = button->action.macro; @@ -1184,17 +1210,20 @@ ratbag_button_set_macro_event(struct ratbag_button *button, macro->events[index].type = type; break; default: - return -EINVAL; + return RATBAG_ERROR_VALUE; } return 0; } -LIBRATBAG_EXPORT int +LIBRATBAG_EXPORT enum ratbag_error_code ratbag_button_write_macro(struct ratbag_button *button) { - return button->profile->device->driver->write_button(button, &button->action); + int rc; + rc = button->profile->device->driver->write_button(button, &button->action); + + return rc == 0 ? RATBAG_SUCCESS : RATBAG_ERROR_DEVICE; } LIBRATBAG_EXPORT enum ratbag_macro_event_type diff --git a/src/libratbag.h b/src/libratbag.h index 2606288e..a556b0ca 100644 --- a/src/libratbag.h +++ b/src/libratbag.h @@ -125,6 +125,48 @@ struct ratbag_button; */ struct ratbag_resolution; +/** + * @ingroup base + * + * Error codes used by libratbag. + */ +enum ratbag_error_code { + RATBAG_SUCCESS = 0, + + /** + * An error occured on the device. Either the device is not a + * libratbag device or communication with the device failed. + */ + RATBAG_ERROR_DEVICE = -1000, + + /** + * Insufficient capabilities. This error occurs when a requestd change is + * beyond the device's capabilities. + */ + RATBAG_ERROR_CAPABILITY = -1001, + + /** + * Invalid value or value range. The provided value or value range + * is outside of the legal or supported range. + */ + RATBAG_ERROR_VALUE = -1002, + + /** + * A low-level system error has occured, e.g. a failure to access + * files that should be there. This error is usually unrecoverable + * and libratbag will print a log message with details about the + * error. + */ + RATBAG_ERROR_SYSTEM = -1003, + + /** + * Implementation bug, either in libratbag or in the caller. This + * error is usually unrecoverable and libratbag will print a log + * message with details about the + * error. + */ + RATBAG_ERROR_IMPLEMENTATION = -1004, +}; /** * @ingroup base @@ -325,12 +367,18 @@ ratbag_unref(struct ratbag *ratbag); * The device is refcounted with an initial value of at least 1. * Use ratbag_device_unref() to release the device. * - * @return A new device based on the udev device, or NULL in case of - * failure. + * @param ratbag A previously initialized ratbag context + * @param udev_device The udev device that points at the device + * @param device Set to a new device based on the udev device. + * + * @return 0 on success or the error. + * @retval RATBAG_ERROR_DEVICE The given device does not exist or is not + * supported by libratbag. */ -struct ratbag_device* +enum ratbag_error_code ratbag_device_new_from_udev_device(struct ratbag *ratbag, - struct udev_device *device); + struct udev_device *udev_device, + struct ratbag_device **device); /** * @ingroup device @@ -600,9 +648,9 @@ ratbag_profile_is_active(struct ratbag_profile *profile); * * @param profile The profile to make the active profile. * - * @return 0 on success or nonzero otherwise. + * @return 0 on success or an error code otherwise */ -int +enum ratbag_error_code ratbag_profile_set_active(struct ratbag_profile *profile); /** @@ -740,9 +788,9 @@ ratbag_resolution_has_capability(struct ratbag_resolution *resolution, * @param resolution A previously initialized ratbag resolution * @param dpi Set to the resolution in dpi, 0 to disable * - * @return zero on success, non-zero otherwise + * @return zero on success or an error code on failure */ -int +enum ratbag_error_code ratbag_resolution_set_dpi(struct ratbag_resolution *resolution, unsigned int dpi); @@ -766,9 +814,9 @@ ratbag_resolution_set_dpi(struct ratbag_resolution *resolution, * @param x The x resolution in dpi * @param y The y resolution in dpi * - * @return zero on success, non-zero otherwise + * @return zero on success or an error code on failure */ -int +enum ratbag_error_code ratbag_resolution_set_dpi_xy(struct ratbag_resolution *resolution, unsigned int x, unsigned int y); @@ -836,9 +884,9 @@ ratbag_resolution_get_dpi_y(struct ratbag_resolution *resolution); * @param resolution A previously initialized ratbag resolution * @param hz Set to the report rate in Hz, may be 0 * - * @return zero on success, non-zero otherwise + * @return zero on success or an error code on failure */ -int +enum ratbag_error_code ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution, unsigned int hz); @@ -856,7 +904,7 @@ ratbag_resolution_set_report_rate(struct ratbag_resolution *resolution, * * @param resolution A previously initialized ratbag resolution * - * @return zero on success, non-zero otherwise + * @return The report rate for this resolution in Hz */ int ratbag_resolution_get_report_rate(struct ratbag_resolution *resolution); @@ -872,9 +920,9 @@ ratbag_resolution_get_report_rate(struct ratbag_resolution *resolution); * * @param resolution A previously initialized ratbag resolution * - * @return zero on success, non-zero otherwise + * @return zero on success or an error code on failure */ -int +enum ratbag_error_code ratbag_resolution_set_active(struct ratbag_resolution *resolution); /** @@ -906,9 +954,9 @@ ratbag_resolution_is_active(const struct ratbag_resolution *resolution); * * @param resolution A previously initialized ratbag resolution * - * @return zero on success, non-zero otherwise + * @return zero on success or an error code on failure */ -int +enum ratbag_error_code ratbag_resolution_set_default(struct ratbag_resolution *resolution); /** @@ -1165,12 +1213,12 @@ ratbag_button_get_button(struct ratbag_button *button); * * @param button A previously initialized ratbag button * @param btn The logical button number to assign to this button. - * @return 0 on success or nonzero otherwise. On success, the button's + * @return 0 on success or an error code otherwise. On success, the button's * action is set to @ref RATBAG_BUTTON_ACTION_TYPE_BUTTON. * * @see ratbag_button_get_button */ -int +enum ratbag_error_code ratbag_button_set_button(struct ratbag_button *button, unsigned int btn); @@ -1197,12 +1245,12 @@ ratbag_button_get_special(struct ratbag_button *button); * * @param button A previously initialized ratbag button * @param action The special action to assign to this button. - * @return 0 on success or nonzero otherwise. On success, the button's + * @return 0 on success or an error code otherwise. On success, the button's * action is set to @ref RATBAG_BUTTON_ACTION_TYPE_SPECIAL. * * @see ratbag_button_get_button */ -int +enum ratbag_error_code ratbag_button_set_special(struct ratbag_button *button, enum ratbag_button_action_special action); @@ -1243,10 +1291,10 @@ ratbag_button_get_key(struct ratbag_button *button, * @param sz The size of the modifiers array. sz may be 0 if no modifiers * are required. * - * @return 0 on success or nonzero otherwise. On success, the button's + * @return 0 on success or an error code otherwise. On success, the button's * action is set to @ref RATBAG_BUTTON_ACTION_TYPE_KEY. */ -int +enum ratbag_error_code ratbag_button_set_key(struct ratbag_button *button, unsigned int key, unsigned int *modifiers, @@ -1257,10 +1305,10 @@ ratbag_button_set_key(struct ratbag_button *button, * * @param button A previously initialized ratbag button * - * @return 0 on success or nonzero otherwise. On success, the button's + * @return 0 on success or an error code otherwise. On success, the button's * action is set to @ref RATBAG_BUTTON_ACTION_TYPE_NONE. */ -int +enum ratbag_error_code ratbag_button_disable(struct ratbag_button *button); /** @@ -1356,10 +1404,10 @@ ratbag_button_get_macro_event_timeout(struct ratbag_button *button, unsigned int * Sets the button's action to @ref RATBAG_BUTTON_ACTION_TYPE_MACRO and * allocates the required memory to store the macro. */ -int +enum ratbag_error_code ratbag_button_set_macro(struct ratbag_button *button, const char *name); -int +enum ratbag_error_code ratbag_button_write_macro(struct ratbag_button *button); /** @@ -1368,7 +1416,7 @@ ratbag_button_write_macro(struct ratbag_button *button); * Sets the macro's event at the given index to the given type with the * key code or timeout given. */ -int +enum ratbag_error_code ratbag_button_set_macro_event(struct ratbag_button *button, unsigned int index, enum ratbag_macro_event_type type, diff --git a/src/libratbag.sym b/src/libratbag.sym index 604a86ad..6493e194 100644 --- a/src/libratbag.sym +++ b/src/libratbag.sym @@ -1,6 +1,6 @@ /* in alphabetical order! */ -LIBRATBAG_0.2.0 { +LIBRATBAG_0.3.0 { global: ratbag_create_context; ratbag_button_disable; diff --git a/tools/shared.c b/tools/shared.c index 9ac94d66..20a207fe 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -236,13 +236,17 @@ ratbag_cmd_open_device(struct ratbag *ratbag, const char *path) struct ratbag_device *device; _cleanup_udev_unref_ struct udev *udev = NULL; _cleanup_udev_device_unref_ struct udev_device *udev_device = NULL; + enum ratbag_error_code error; udev = udev_new(); udev_device = udev_device_from_path(udev, path); if (!udev_device) return NULL; - device = ratbag_device_new_from_udev_device(ratbag, udev_device); + error = ratbag_device_new_from_udev_device(ratbag, udev_device, + &device); + if (error != RATBAG_SUCCESS) + return NULL; return device; }