From bf452ed81d311e03638258de5c6dfbb4b0f121e2 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Thu, 20 Feb 2020 20:33:30 -0500 Subject: [PATCH 1/4] Add an optional warn_unused_result attribute to functs which return vals The warn_unused_result attribute causes a warning to be emitted if a caller of the function with this attribute does not use its return value. This is normally useful for functions where not checking the result is either a security problem or normally bug, but can just point out problems in end user code. As various backends (USB, Ethernet) are sometimes not 100%, this helps ensure that users are checking for various error codes, and hopefully geting meaningful error messages, as requested in #263. However, this would make most code pretty noisey to compile, only turn this on if asked (ie someone defines IIO_CHECK_RET) Signed-off-by: Robin Getz --- iio.h | 244 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 125 insertions(+), 119 deletions(-) diff --git a/iio.h b/iio.h index 5c11fcefe..958caa6cf 100644 --- a/iio.h +++ b/iio.h @@ -59,10 +59,16 @@ typedef ptrdiff_t ssize_t; #define __pure __attribute__((pure)) #endif #define __notused __attribute__((unused)) +#ifdef IIO_CHECK_RET +#define __check_ret __attribute__((warn_unused_result)) +#else +#define __check_ret +#endif #else #define __cnst #define __pure #define __notused +#define __check_ret #endif #ifdef _WIN32 @@ -193,7 +199,7 @@ enum iio_modifier { * @param flags Unused for now. Set to 0. * @return on success, a pointer to a iio_scan_context structure * @return On failure, NULL is returned and errno is set appropriately */ -__api struct iio_scan_context * iio_create_scan_context( +__api __check_ret struct iio_scan_context * iio_create_scan_context( const char *backend, unsigned int flags); @@ -211,7 +217,7 @@ __api void iio_scan_context_destroy(struct iio_scan_context *ctx); * @returns On success, the number of contexts found. * @returns On failure, a negative error number. */ -__api ssize_t iio_scan_context_get_info_list(struct iio_scan_context *ctx, +__api __check_ret ssize_t iio_scan_context_get_info_list(struct iio_scan_context *ctx, struct iio_context_info ***info); @@ -225,7 +231,7 @@ __api void iio_context_info_list_free(struct iio_context_info **info); * @param info A pointer to an iio_context_info structure * @return A pointer to a static NULL-terminated string */ -__api __pure const char * iio_context_info_get_description( +__api __check_ret __pure const char * iio_context_info_get_description( const struct iio_context_info *info); @@ -233,7 +239,7 @@ __api __pure const char * iio_context_info_get_description( * @param info A pointer to an iio_context_info structure * @return A pointer to a static NULL-terminated string */ -__api __pure const char * iio_context_info_get_uri( +__api __check_ret __pure const char * iio_context_info_get_uri( const struct iio_context_info *info); @@ -264,14 +270,14 @@ __api void iio_strerror(int err, char *dst, size_t len); * @return True if the backend is available, false otherwise * * Introduced in version 0.9. */ -__api __cnst bool iio_has_backend(const char *backend); +__api __check_ret __cnst bool iio_has_backend(const char *backend); /** @brief Get the number of available backends * @return The number of available backends * * Introduced in version 0.9. */ -__api __cnst unsigned int iio_get_backends_count(void); +__api __check_ret __cnst unsigned int iio_get_backends_count(void); /** @brief Retrieve the name of a given backend @@ -280,7 +286,7 @@ __api __cnst unsigned int iio_get_backends_count(void); * @return If the index is invalid, NULL is returned * * Introduced in version 0.9. */ -__api __cnst const char * iio_get_backend(unsigned int index); +__api __check_ret __cnst const char * iio_get_backend(unsigned int index); /** @} *//* ------------------------------------------------------------------*/ @@ -300,13 +306,13 @@ __api __cnst const char * iio_get_backend(unsigned int index); * set to an empty string, the server will be discovered using ZeroConf. * If the environment variable is not set, a local context will be created * instead. */ -__api struct iio_context * iio_create_default_context(void); +__api __check_ret struct iio_context * iio_create_default_context(void); /** @brief Create a context from local IIO devices (Linux only) * @return On success, A pointer to an iio_context structure * @return On failure, NULL is returned and errno is set appropriately */ -__api struct iio_context * iio_create_local_context(void); +__api __check_ret struct iio_context * iio_create_local_context(void); /** @brief Create a context from a XML file @@ -316,7 +322,7 @@ __api struct iio_context * iio_create_local_context(void); * * NOTE: The format of the XML must comply to the one returned by * iio_context_get_xml. */ -__api struct iio_context * iio_create_xml_context(const char *xml_file); +__api __check_ret struct iio_context * iio_create_xml_context(const char *xml_file); /** @brief Create a context from XML data in memory @@ -327,7 +333,7 @@ __api struct iio_context * iio_create_xml_context(const char *xml_file); * * NOTE: The format of the XML must comply to the one returned by * iio_context_get_xml */ -__api struct iio_context * iio_create_xml_context_mem( +__api __check_ret struct iio_context * iio_create_xml_context_mem( const char *xml, size_t len); @@ -335,7 +341,7 @@ __api struct iio_context * iio_create_xml_context_mem( * @param host Hostname, IPv4 or IPv6 address where the IIO Daemon is running * @return On success, a pointer to an iio_context structure * @return On failure, NULL is returned and errno is set appropriately */ -__api struct iio_context * iio_create_network_context(const char *host); +__api __check_ret struct iio_context * iio_create_network_context(const char *host); /** @brief Create a context from a URI description @@ -360,14 +366,14 @@ __api struct iio_context * iio_create_network_context(const char *host); * ('\0' none, 'x' Xon Xoff, 'r' RTSCTS, 'd' DTRDSR) parts separated * with a comma. For example "serial:/dev/ttyUSB0,115200", * "serial:/dev/ttyUSB0,115200,n,8,1"*/ -__api struct iio_context * iio_create_context_from_uri(const char *uri); +__api __check_ret struct iio_context * iio_create_context_from_uri(const char *uri); /** @brief Duplicate a pre-existing IIO context * @param ctx A pointer to an iio_context structure * @return On success, A pointer to an iio_context structure * @return On failure, NULL is returned and errno is set appropriately */ -__api struct iio_context * iio_context_clone(const struct iio_context *ctx); +__api __check_ret struct iio_context * iio_context_clone(const struct iio_context *ctx); /** @brief Destroy the given context @@ -384,14 +390,14 @@ __api void iio_context_destroy(struct iio_context *ctx); * @param git_tag A pointer to a 8-characters buffer (NULL accepted) * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_context_get_version(const struct iio_context *ctx, +__api __check_ret int iio_context_get_version(const struct iio_context *ctx, unsigned int *major, unsigned int *minor, char git_tag[8]); /** @brief Obtain a XML representation of the given context * @param ctx A pointer to an iio_context structure * @return A pointer to a static NULL-terminated string */ -__api __pure const char * iio_context_get_xml(const struct iio_context *ctx); +__api __check_ret __pure const char * iio_context_get_xml(const struct iio_context *ctx); /** @brief Get the name of the given context @@ -401,7 +407,7 @@ __api __pure const char * iio_context_get_xml(const struct iio_context *ctx); * NOTE:The returned string will be local, * xml or network when the context has been * created with the local, xml and network backends respectively.*/ -__api __pure const char * iio_context_get_name(const struct iio_context *ctx); +__api __check_ret __pure const char * iio_context_get_name(const struct iio_context *ctx); /** @brief Get a description of the given context @@ -410,7 +416,7 @@ __api __pure const char * iio_context_get_name(const struct iio_context *ctx); * * NOTE:The returned string will contain human-readable information about * the current context. */ -__api __pure const char * iio_context_get_description( +__api __check_ret __pure const char * iio_context_get_description( const struct iio_context *ctx); @@ -419,7 +425,7 @@ __api __pure const char * iio_context_get_description( * @return The number of context-specific attributes * * Introduced in version 0.9. */ -__api __pure unsigned int iio_context_get_attrs_count( +__api __check_ret __pure unsigned int iio_context_get_attrs_count( const struct iio_context *ctx); @@ -432,7 +438,7 @@ __api __pure unsigned int iio_context_get_attrs_count( * @return On error, a negative errno code is returned * * Introduced in version 0.9. */ -__api int iio_context_get_attr( +__api __check_ret int iio_context_get_attr( const struct iio_context *ctx, unsigned int index, const char **name, const char **value); @@ -445,14 +451,14 @@ __api int iio_context_get_attr( * returned * * Introduced in version 0.9. */ -__api const char * iio_context_get_attr_value( +__api __check_ret const char * iio_context_get_attr_value( const struct iio_context *ctx, const char *name); /** @brief Enumerate the devices found in the given context * @param ctx A pointer to an iio_context structure * @return The number of devices found */ -__api __pure unsigned int iio_context_get_devices_count( +__api __check_ret __pure unsigned int iio_context_get_devices_count( const struct iio_context *ctx); @@ -461,7 +467,7 @@ __api __pure unsigned int iio_context_get_devices_count( * @param index The index corresponding to the device * @return On success, a pointer to an iio_device structure * @return If the index is invalid, NULL is returned */ -__api __pure struct iio_device * iio_context_get_device( +__api __check_ret __pure struct iio_device * iio_context_get_device( const struct iio_context *ctx, unsigned int index); @@ -472,7 +478,7 @@ __api __pure struct iio_device * iio_context_get_device( * @return On success, a pointer to an iio_device structure * @return If the name or ID does not correspond to any known device, NULL is * returned */ -__api __pure struct iio_device * iio_context_find_device( +__api __check_ret __pure struct iio_device * iio_context_find_device( const struct iio_context *ctx, const char *name); @@ -483,7 +489,7 @@ __api __pure struct iio_device * iio_context_find_device( * timeout should occur. * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_context_set_timeout( +__api __check_ret int iio_context_set_timeout( struct iio_context *ctx, unsigned int timeout_ms); @@ -498,14 +504,14 @@ __api int iio_context_set_timeout( /** @brief Retrieve a pointer to the iio_context structure * @param dev A pointer to an iio_device structure * @return A pointer to an iio_context structure */ -__api __pure const struct iio_context * iio_device_get_context( +__api __check_ret __pure const struct iio_context * iio_device_get_context( const struct iio_device *dev); /** @brief Retrieve the device ID (e.g. iio:device0) * @param dev A pointer to an iio_device structure * @return A pointer to a static NULL-terminated string */ -__api __pure const char * iio_device_get_id(const struct iio_device *dev); +__api __check_ret __pure const char * iio_device_get_id(const struct iio_device *dev); /** @brief Retrieve the device name (e.g. xadc) @@ -513,26 +519,26 @@ __api __pure const char * iio_device_get_id(const struct iio_device *dev); * @return A pointer to a static NULL-terminated string * * NOTE: if the device has no name, NULL is returned. */ -__api __pure const char * iio_device_get_name(const struct iio_device *dev); +__api __check_ret __pure const char * iio_device_get_name(const struct iio_device *dev); /** @brief Enumerate the channels of the given device * @param dev A pointer to an iio_device structure * @return The number of channels found */ -__api __pure unsigned int iio_device_get_channels_count( +__api __check_ret __pure unsigned int iio_device_get_channels_count( const struct iio_device *dev); /** @brief Enumerate the device-specific attributes of the given device * @param dev A pointer to an iio_device structure * @return The number of device-specific attributes found */ -__api __pure unsigned int iio_device_get_attrs_count( +__api __check_ret __pure unsigned int iio_device_get_attrs_count( const struct iio_device *dev); /** @brief Enumerate the buffer-specific attributes of the given device * @param dev A pointer to an iio_device structure * @return The number of buffer-specific attributes found */ -__api __pure unsigned int iio_device_get_buffer_attrs_count( +__api __check_ret __pure unsigned int iio_device_get_buffer_attrs_count( const struct iio_device *dev); /** @brief Get the channel present at the given index @@ -540,7 +546,7 @@ __api __pure unsigned int iio_device_get_buffer_attrs_count( * @param index The index corresponding to the channel * @return On success, a pointer to an iio_channel structure * @return If the index is invalid, NULL is returned */ -__api __pure struct iio_channel * iio_device_get_channel( +__api __check_ret __pure struct iio_channel * iio_device_get_channel( const struct iio_device *dev, unsigned int index); @@ -549,7 +555,7 @@ __api __pure struct iio_channel * iio_device_get_channel( * @param index The index corresponding to the attribute * @return On success, a pointer to a static NULL-terminated string * @return If the index is invalid, NULL is returned */ -__api __pure const char * iio_device_get_attr( +__api __check_ret __pure const char * iio_device_get_attr( const struct iio_device *dev, unsigned int index); /** @brief Get the buffer-specific attribute present at the given index @@ -557,7 +563,7 @@ __api __pure const char * iio_device_get_attr( * @param index The index corresponding to the attribute * @return On success, a pointer to a static NULL-terminated string * @return If the index is invalid, NULL is returned */ -__api __pure const char * iio_device_get_buffer_attr( +__api __check_ret __pure const char * iio_device_get_buffer_attr( const struct iio_device *dev, unsigned int index); /** @brief Try to find a channel structure by its name of ID @@ -568,7 +574,7 @@ __api __pure const char * iio_device_get_buffer_attr( * @return On success, a pointer to an iio_channel structure * @return If the name or ID does not correspond to any known channel of the * given device, NULL is returned */ -__api __pure struct iio_channel * iio_device_find_channel( +__api __check_ret __pure struct iio_channel * iio_device_find_channel( const struct iio_device *dev, const char *name, bool output); @@ -583,7 +589,7 @@ __api __pure struct iio_channel * iio_device_find_channel( * NOTE: This function is useful to detect the presence of an attribute. * It can also be used to retrieve the name of an attribute as a pointer to a * static string from a dynamically allocated string. */ -__api __pure const char * iio_device_find_attr( +__api __check_ret __pure const char * iio_device_find_attr( const struct iio_device *dev, const char *name); /** @brief Try to find a buffer-specific attribute by its name @@ -597,7 +603,7 @@ __api __pure const char * iio_device_find_attr( * NOTE: This function is useful to detect the presence of an attribute. * It can also be used to retrieve the name of an attribute as a pointer to a * static string from a dynamically allocated string. */ -__api __pure const char * iio_device_find_buffer_attr( +__api __check_ret __pure const char * iio_device_find_buffer_attr( const struct iio_device *dev, const char *name); /** @brief Read the content of the given device-specific attribute @@ -621,7 +627,7 @@ __api __pure const char * iio_device_find_buffer_attr( * returned when reading the attribute; if positive, it corresponds to the * length of the data read. In that case, the rest of the block contains * the data. */ -__api ssize_t iio_device_attr_read(const struct iio_device *dev, +__api __check_ret ssize_t iio_device_attr_read(const struct iio_device *dev, const char *attr, char *dst, size_t len); @@ -635,7 +641,7 @@ __api ssize_t iio_device_attr_read(const struct iio_device *dev, * NOTE: This function is especially useful when used with the network * backend, as all the device-specific attributes are read in one single * command. */ -__api int iio_device_attr_read_all(struct iio_device *dev, +__api __check_ret int iio_device_attr_read_all(struct iio_device *dev, int (*cb)(struct iio_device *dev, const char *attr, const char *value, size_t len, void *d), void *data); @@ -648,7 +654,7 @@ __api int iio_device_attr_read_all(struct iio_device *dev, * @param val A pointer to a bool variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_attr_read_bool(const struct iio_device *dev, +__api __check_ret int iio_device_attr_read_bool(const struct iio_device *dev, const char *attr, bool *val); @@ -659,7 +665,7 @@ __api int iio_device_attr_read_bool(const struct iio_device *dev, * @param val A pointer to a long long variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_attr_read_longlong(const struct iio_device *dev, +__api __check_ret int iio_device_attr_read_longlong(const struct iio_device *dev, const char *attr, long long *val); @@ -670,7 +676,7 @@ __api int iio_device_attr_read_longlong(const struct iio_device *dev, * @param val A pointer to a double variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_attr_read_double(const struct iio_device *dev, +__api __check_ret int iio_device_attr_read_double(const struct iio_device *dev, const char *attr, double *val); @@ -692,7 +698,7 @@ __api int iio_device_attr_read_double(const struct iio_device *dev, * network order. If negative, the attribute is not written; if positive, * it corresponds to the length of the data to write. In that case, the rest * of the block must contain the data. */ -__api ssize_t iio_device_attr_write(const struct iio_device *dev, +__api __check_ret ssize_t iio_device_attr_write(const struct iio_device *dev, const char *attr, const char *src); @@ -704,7 +710,7 @@ __api ssize_t iio_device_attr_write(const struct iio_device *dev, * @param len The number of bytes that should be written * @return On success, the number of bytes written * @return On error, a negative errno code is returned */ -__api ssize_t iio_device_attr_write_raw(const struct iio_device *dev, +__api __check_ret ssize_t iio_device_attr_write_raw(const struct iio_device *dev, const char *attr, const void *src, size_t len); @@ -718,7 +724,7 @@ __api ssize_t iio_device_attr_write_raw(const struct iio_device *dev, * NOTE: This function is especially useful when used with the network * backend, as all the device-specific attributes are written in one single * command. */ -__api int iio_device_attr_write_all(struct iio_device *dev, +__api __check_ret int iio_device_attr_write_all(struct iio_device *dev, ssize_t (*cb)(struct iio_device *dev, const char *attr, void *buf, size_t len, void *d), void *data); @@ -731,7 +737,7 @@ __api int iio_device_attr_write_all(struct iio_device *dev, * @param val A bool value to set the attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_attr_write_bool(const struct iio_device *dev, +__api __check_ret int iio_device_attr_write_bool(const struct iio_device *dev, const char *attr, bool val); @@ -742,7 +748,7 @@ __api int iio_device_attr_write_bool(const struct iio_device *dev, * @param val A long long value to set the attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_attr_write_longlong(const struct iio_device *dev, +__api __check_ret int iio_device_attr_write_longlong(const struct iio_device *dev, const char *attr, long long val); @@ -753,7 +759,7 @@ __api int iio_device_attr_write_longlong(const struct iio_device *dev, * @param val A double value to set the attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_attr_write_double(const struct iio_device *dev, +__api __check_ret int iio_device_attr_write_double(const struct iio_device *dev, const char *attr, double val); /** @brief Read the content of the given buffer-specific attribute @@ -778,7 +784,7 @@ __api int iio_device_attr_write_double(const struct iio_device *dev, * returned when reading the attribute; if positive, it corresponds to the * length of the data read. In that case, the rest of the block contains * the data. */ -__api ssize_t iio_device_buffer_attr_read(const struct iio_device *dev, +__api __check_ret ssize_t iio_device_buffer_attr_read(const struct iio_device *dev, const char *attr, char *dst, size_t len); /** @brief Read the content of all buffer-specific attributes @@ -791,7 +797,7 @@ __api ssize_t iio_device_buffer_attr_read(const struct iio_device *dev, * NOTE: This function is especially useful when used with the network * backend, as all the buffer-specific attributes are read in one single * command. */ -__api int iio_device_buffer_attr_read_all(struct iio_device *dev, +__api __check_ret int iio_device_buffer_attr_read_all(struct iio_device *dev, int (*cb)(struct iio_device *dev, const char *attr, const char *value, size_t len, void *d), void *data); @@ -804,7 +810,7 @@ __api int iio_device_buffer_attr_read_all(struct iio_device *dev, * @param val A pointer to a bool variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_buffer_attr_read_bool(const struct iio_device *dev, +__api __check_ret int iio_device_buffer_attr_read_bool(const struct iio_device *dev, const char *attr, bool *val); @@ -815,7 +821,7 @@ __api int iio_device_buffer_attr_read_bool(const struct iio_device *dev, * @param val A pointer to a long long variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_buffer_attr_read_longlong(const struct iio_device *dev, +__api __check_ret int iio_device_buffer_attr_read_longlong(const struct iio_device *dev, const char *attr, long long *val); @@ -826,7 +832,7 @@ __api int iio_device_buffer_attr_read_longlong(const struct iio_device *dev, * @param val A pointer to a double variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_buffer_attr_read_double(const struct iio_device *dev, +__api __check_ret int iio_device_buffer_attr_read_double(const struct iio_device *dev, const char *attr, double *val); @@ -849,7 +855,7 @@ __api int iio_device_buffer_attr_read_double(const struct iio_device *dev, * network order. If negative, the attribute is not written; if positive, * it corresponds to the length of the data to write. In that case, the rest * of the block must contain the data. */ -__api ssize_t iio_device_buffer_attr_write(const struct iio_device *dev, +__api __check_ret ssize_t iio_device_buffer_attr_write(const struct iio_device *dev, const char *attr, const char *src); @@ -861,7 +867,7 @@ __api ssize_t iio_device_buffer_attr_write(const struct iio_device *dev, * @param len The number of bytes that should be written * @return On success, the number of bytes written * @return On error, a negative errno code is returned */ -__api ssize_t iio_device_buffer_attr_write_raw(const struct iio_device *dev, +__api __check_ret ssize_t iio_device_buffer_attr_write_raw(const struct iio_device *dev, const char *attr, const void *src, size_t len); @@ -875,7 +881,7 @@ __api ssize_t iio_device_buffer_attr_write_raw(const struct iio_device *dev, * NOTE: This function is especially useful when used with the network * backend, as all the buffer-specific attributes are written in one single * command. */ -__api int iio_device_buffer_attr_write_all(struct iio_device *dev, +__api __check_ret int iio_device_buffer_attr_write_all(struct iio_device *dev, ssize_t (*cb)(struct iio_device *dev, const char *attr, void *buf, size_t len, void *d), void *data); @@ -888,7 +894,7 @@ __api int iio_device_buffer_attr_write_all(struct iio_device *dev, * @param val A bool value to set the attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_buffer_attr_write_bool(const struct iio_device *dev, +__api __check_ret int iio_device_buffer_attr_write_bool(const struct iio_device *dev, const char *attr, bool val); @@ -899,7 +905,7 @@ __api int iio_device_buffer_attr_write_bool(const struct iio_device *dev, * @param val A long long value to set the attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_buffer_attr_write_longlong(const struct iio_device *dev, +__api __check_ret int iio_device_buffer_attr_write_longlong(const struct iio_device *dev, const char *attr, long long val); @@ -910,7 +916,7 @@ __api int iio_device_buffer_attr_write_longlong(const struct iio_device *dev, * @param val A double value to set the attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_buffer_attr_write_double(const struct iio_device *dev, +__api __check_ret int iio_device_buffer_attr_write_double(const struct iio_device *dev, const char *attr, double val); @@ -933,7 +939,7 @@ __api void * iio_device_get_data(const struct iio_device *dev); * to the associated trigger device. * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_get_trigger(const struct iio_device *dev, +__api __check_ret int iio_device_get_trigger(const struct iio_device *dev, const struct iio_device **trigger); @@ -943,14 +949,14 @@ __api int iio_device_get_trigger(const struct iio_device *dev, * trigger that should be associated. * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_set_trigger(const struct iio_device *dev, +__api __check_ret int iio_device_set_trigger(const struct iio_device *dev, const struct iio_device *trigger); /** @brief Return True if the given device is a trigger * @param dev A pointer to an iio_device structure * @return True if the device is a trigger, False otherwise */ -__api __pure bool iio_device_is_trigger(const struct iio_device *dev); +__api __check_ret __pure bool iio_device_is_trigger(const struct iio_device *dev); /** @brief Configure the number of kernel buffers for a device * @@ -959,7 +965,7 @@ __api __pure bool iio_device_is_trigger(const struct iio_device *dev); * @param nb_buffers The number of buffers * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_set_kernel_buffers_count(const struct iio_device *dev, +__api __check_ret int iio_device_set_kernel_buffers_count(const struct iio_device *dev, unsigned int nb_buffers); /** @} *//* ------------------------------------------------------------------*/ @@ -973,14 +979,14 @@ __api int iio_device_set_kernel_buffers_count(const struct iio_device *dev, /** @brief Retrieve a pointer to the iio_device structure * @param chn A pointer to an iio_channel structure * @return A pointer to an iio_device structure */ -__api __pure const struct iio_device * iio_channel_get_device( +__api __check_ret __pure const struct iio_device * iio_channel_get_device( const struct iio_channel *chn); /** @brief Retrieve the channel ID (e.g. voltage0) * @param chn A pointer to an iio_channel structure * @return A pointer to a static NULL-terminated string */ -__api __pure const char * iio_channel_get_id(const struct iio_channel *chn); +__api __check_ret __pure const char * iio_channel_get_id(const struct iio_channel *chn); /** @brief Retrieve the channel name (e.g. vccint) @@ -988,13 +994,13 @@ __api __pure const char * iio_channel_get_id(const struct iio_channel *chn); * @return A pointer to a static NULL-terminated string * * NOTE: if the channel has no name, NULL is returned. */ -__api __pure const char * iio_channel_get_name(const struct iio_channel *chn); +__api __check_ret __pure const char * iio_channel_get_name(const struct iio_channel *chn); /** @brief Return True if the given channel is an output channel * @param chn A pointer to an iio_channel structure * @return True if the channel is an output channel, False otherwise */ -__api __pure bool iio_channel_is_output(const struct iio_channel *chn); +__api __check_ret __pure bool iio_channel_is_output(const struct iio_channel *chn); /** @brief Return True if the given channel is a scan element @@ -1004,13 +1010,13 @@ __api __pure bool iio_channel_is_output(const struct iio_channel *chn); * NOTE: a channel that is a scan element is a channel that can * generate samples (for an input channel) or receive samples (for an output * channel) after being enabled. */ -__api __pure bool iio_channel_is_scan_element(const struct iio_channel *chn); +__api __check_ret __pure bool iio_channel_is_scan_element(const struct iio_channel *chn); /** @brief Enumerate the channel-specific attributes of the given channel * @param chn A pointer to an iio_channel structure * @return The number of channel-specific attributes found */ -__api __pure unsigned int iio_channel_get_attrs_count( +__api __check_ret __pure unsigned int iio_channel_get_attrs_count( const struct iio_channel *chn); @@ -1019,7 +1025,7 @@ __api __pure unsigned int iio_channel_get_attrs_count( * @param index The index corresponding to the attribute * @return On success, a pointer to a static NULL-terminated string * @return If the index is invalid, NULL is returned */ -__api __pure const char * iio_channel_get_attr( +__api __check_ret __pure const char * iio_channel_get_attr( const struct iio_channel *chn, unsigned int index); @@ -1034,7 +1040,7 @@ __api __pure const char * iio_channel_get_attr( * NOTE: This function is useful to detect the presence of an attribute. * It can also be used to retrieve the name of an attribute as a pointer to a * static string from a dynamically allocated string. */ -__api __pure const char * iio_channel_find_attr( +__api __check_ret __pure const char * iio_channel_find_attr( const struct iio_channel *chn, const char *name); @@ -1044,7 +1050,7 @@ __api __pure const char * iio_channel_find_attr( * attribute * @return On success, a pointer to a static NULL-terminated string * @return If the attribute name is unknown, NULL is returned */ -__api __pure const char * iio_channel_attr_get_filename( +__api __check_ret __pure const char * iio_channel_attr_get_filename( const struct iio_channel *chn, const char *attr); @@ -1069,7 +1075,7 @@ __api __pure const char * iio_channel_attr_get_filename( * returned when reading the attribute; if positive, it corresponds to the * length of the data read. In that case, the rest of the block contains * the data. */ -__api ssize_t iio_channel_attr_read(const struct iio_channel *chn, +__api __check_ret ssize_t iio_channel_attr_read(const struct iio_channel *chn, const char *attr, char *dst, size_t len); @@ -1083,7 +1089,7 @@ __api ssize_t iio_channel_attr_read(const struct iio_channel *chn, * NOTE: This function is especially useful when used with the network * backend, as all the channel-specific attributes are read in one single * command. */ -__api int iio_channel_attr_read_all(struct iio_channel *chn, +__api __check_ret int iio_channel_attr_read_all(struct iio_channel *chn, int (*cb)(struct iio_channel *chn, const char *attr, const char *val, size_t len, void *d), void *data); @@ -1096,7 +1102,7 @@ __api int iio_channel_attr_read_all(struct iio_channel *chn, * @param val A pointer to a bool variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_channel_attr_read_bool(const struct iio_channel *chn, +__api __check_ret int iio_channel_attr_read_bool(const struct iio_channel *chn, const char *attr, bool *val); @@ -1107,7 +1113,7 @@ __api int iio_channel_attr_read_bool(const struct iio_channel *chn, * @param val A pointer to a long long variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_channel_attr_read_longlong(const struct iio_channel *chn, +__api __check_ret int iio_channel_attr_read_longlong(const struct iio_channel *chn, const char *attr, long long *val); @@ -1118,7 +1124,7 @@ __api int iio_channel_attr_read_longlong(const struct iio_channel *chn, * @param val A pointer to a double variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_channel_attr_read_double(const struct iio_channel *chn, +__api __check_ret int iio_channel_attr_read_double(const struct iio_channel *chn, const char *attr, double *val); @@ -1140,7 +1146,7 @@ __api int iio_channel_attr_read_double(const struct iio_channel *chn, * network order. If negative, the attribute is not written; if positive, * it corresponds to the length of the data to write. In that case, the rest * of the block must contain the data. */ -__api ssize_t iio_channel_attr_write(const struct iio_channel *chn, +__api __check_ret ssize_t iio_channel_attr_write(const struct iio_channel *chn, const char *attr, const char *src); @@ -1152,7 +1158,7 @@ __api ssize_t iio_channel_attr_write(const struct iio_channel *chn, * @param len The number of bytes that should be written * @return On success, the number of bytes written * @return On error, a negative errno code is returned */ -__api ssize_t iio_channel_attr_write_raw(const struct iio_channel *chn, +__api __check_ret ssize_t iio_channel_attr_write_raw(const struct iio_channel *chn, const char *attr, const void *src, size_t len); @@ -1166,7 +1172,7 @@ __api ssize_t iio_channel_attr_write_raw(const struct iio_channel *chn, * NOTE: This function is especially useful when used with the network * backend, as all the channel-specific attributes are written in one single * command. */ -__api int iio_channel_attr_write_all(struct iio_channel *chn, +__api __check_ret int iio_channel_attr_write_all(struct iio_channel *chn, ssize_t (*cb)(struct iio_channel *chn, const char *attr, void *buf, size_t len, void *d), void *data); @@ -1179,7 +1185,7 @@ __api int iio_channel_attr_write_all(struct iio_channel *chn, * @param val A bool value to set the attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_channel_attr_write_bool(const struct iio_channel *chn, +__api __check_ret int iio_channel_attr_write_bool(const struct iio_channel *chn, const char *attr, bool val); @@ -1190,7 +1196,7 @@ __api int iio_channel_attr_write_bool(const struct iio_channel *chn, * @param val A long long value to set the attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_channel_attr_write_longlong(const struct iio_channel *chn, +__api __check_ret int iio_channel_attr_write_longlong(const struct iio_channel *chn, const char *attr, long long val); @@ -1201,7 +1207,7 @@ __api int iio_channel_attr_write_longlong(const struct iio_channel *chn, * @param val A double value to set the attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_channel_attr_write_double(const struct iio_channel *chn, +__api __check_ret int iio_channel_attr_write_double(const struct iio_channel *chn, const char *attr, double val); @@ -1222,7 +1228,7 @@ __api void iio_channel_disable(struct iio_channel *chn); /** @brief Returns True if the channel is enabled * @param chn A pointer to an iio_channel structure * @return True if the channel is enabled, False otherwise */ -__api bool iio_channel_is_enabled(const struct iio_channel *chn); +__api __check_ret bool iio_channel_is_enabled(const struct iio_channel *chn); /** @brief Demultiplex the samples of a given channel @@ -1232,7 +1238,7 @@ __api bool iio_channel_is_enabled(const struct iio_channel *chn); * stored * @param len The available length of the memory area, in bytes * @return The size of the demultiplexed data, in bytes */ -__api size_t iio_channel_read_raw(const struct iio_channel *chn, +__api __check_ret size_t iio_channel_read_raw(const struct iio_channel *chn, struct iio_buffer *buffer, void *dst, size_t len); @@ -1243,7 +1249,7 @@ __api size_t iio_channel_read_raw(const struct iio_channel *chn, * stored * @param len The available length of the memory area, in bytes * @return The size of the converted data, in bytes */ -__api size_t iio_channel_read(const struct iio_channel *chn, +__api __check_ret size_t iio_channel_read(const struct iio_channel *chn, struct iio_buffer *buffer, void *dst, size_t len); @@ -1254,7 +1260,7 @@ __api size_t iio_channel_read(const struct iio_channel *chn, * be read from * @param len The length of the memory area, in bytes * @return The number of bytes actually multiplexed */ -__api size_t iio_channel_write_raw(const struct iio_channel *chn, +__api __check_ret size_t iio_channel_write_raw(const struct iio_channel *chn, struct iio_buffer *buffer, const void *src, size_t len); @@ -1265,7 +1271,7 @@ __api size_t iio_channel_write_raw(const struct iio_channel *chn, * be read from * @param len The length of the memory area, in bytes * @return The number of bytes actually converted and multiplexed */ -__api size_t iio_channel_write(const struct iio_channel *chn, +__api __check_ret size_t iio_channel_write(const struct iio_channel *chn, struct iio_buffer *buffer, const void *src, size_t len); @@ -1284,14 +1290,14 @@ __api void * iio_channel_get_data(const struct iio_channel *chn); /** @brief Get the type of the given channel * @param chn A pointer to an iio_channel structure * @return The type of the channel */ -__api __pure enum iio_chan_type iio_channel_get_type( +__api __check_ret __pure enum iio_chan_type iio_channel_get_type( const struct iio_channel *chn); /** @brief Get the modifier type of the given channel * @param chn A pointer to an iio_channel structure * @return The modifier type of the channel */ -__api __pure enum iio_modifier iio_channel_get_modifier( +__api __check_ret __pure enum iio_modifier iio_channel_get_modifier( const struct iio_channel *chn); @@ -1306,7 +1312,7 @@ __api __pure enum iio_modifier iio_channel_get_modifier( /** @brief Retrieve a pointer to the iio_device structure * @param buf A pointer to an iio_buffer structure * @return A pointer to an iio_device structure */ -__api __pure const struct iio_device * iio_buffer_get_device( +__api __check_ret __pure const struct iio_device * iio_buffer_get_device( const struct iio_buffer *buf); @@ -1319,7 +1325,7 @@ __api __pure const struct iio_device * iio_buffer_get_device( * * NOTE: Channels that have to be written to / read from must be enabled * before creating the buffer. */ -__api struct iio_buffer * iio_device_create_buffer(const struct iio_device *dev, +__api __check_ret struct iio_buffer * iio_device_create_buffer(const struct iio_device *dev, size_t samples_count, bool cyclic); @@ -1337,7 +1343,7 @@ __api void iio_buffer_destroy(struct iio_buffer *buf); * @return On success, valid file descriptor * @return On error, a negative errno code is returned */ -__api int iio_buffer_get_poll_fd(struct iio_buffer *buf); +__api __check_ret int iio_buffer_get_poll_fd(struct iio_buffer *buf); /** @brief Make iio_buffer_refill() and iio_buffer_push() blocking or not * @@ -1350,7 +1356,7 @@ __api int iio_buffer_get_poll_fd(struct iio_buffer *buf); * @return On success, 0 * @return On error, a negative errno code is returned */ -__api int iio_buffer_set_blocking_mode(struct iio_buffer *buf, bool blocking); +__api __check_ret int iio_buffer_set_blocking_mode(struct iio_buffer *buf, bool blocking); /** @brief Fetch more samples from the hardware @@ -1359,7 +1365,7 @@ __api int iio_buffer_set_blocking_mode(struct iio_buffer *buf, bool blocking); * @return On error, a negative errno code is returned * * NOTE: Only valid for input buffers */ -__api ssize_t iio_buffer_refill(struct iio_buffer *buf); +__api __check_ret ssize_t iio_buffer_refill(struct iio_buffer *buf); /** @brief Send the samples to the hardware @@ -1368,7 +1374,7 @@ __api ssize_t iio_buffer_refill(struct iio_buffer *buf); * @return On error, a negative errno code is returned * * NOTE: Only valid for output buffers */ -__api ssize_t iio_buffer_push(struct iio_buffer *buf); +__api __check_ret ssize_t iio_buffer_push(struct iio_buffer *buf); /** @brief Send a given number of samples to the hardware @@ -1378,7 +1384,7 @@ __api ssize_t iio_buffer_push(struct iio_buffer *buf); * @return On error, a negative errno code is returned * * NOTE: Only valid for output buffers */ -__api ssize_t iio_buffer_push_partial(struct iio_buffer *buf, +__api __check_ret ssize_t iio_buffer_push_partial(struct iio_buffer *buf, size_t samples_count); /** @brief Cancel all buffer operations @@ -1436,7 +1442,7 @@ __api void * iio_buffer_first(const struct iio_buffer *buf, * @param buf A pointer to an iio_buffer structure * @return the difference between the addresses of two consecutive samples of * one same channel */ -__api ptrdiff_t iio_buffer_step(const struct iio_buffer *buf); +__api __check_ret ptrdiff_t iio_buffer_step(const struct iio_buffer *buf); /** @brief Get the address that follows the last sample in a buffer @@ -1457,7 +1463,7 @@ __api void * iio_buffer_end(const struct iio_buffer *buf); * * A pointer to the sample itself, * * The length of the sample in bytes, * * The user-specified pointer passed to iio_buffer_foreach_sample. */ -__api ssize_t iio_buffer_foreach_sample(struct iio_buffer *buf, +__api __check_ret ssize_t iio_buffer_foreach_sample(struct iio_buffer *buf, ssize_t (*callback)(const struct iio_channel *chn, void *src, size_t bytes, void *d), void *data); @@ -1522,20 +1528,20 @@ struct iio_data_format { * * NOTE: The sample size is not constant and will change when channels * get enabled or disabled. */ -__api ssize_t iio_device_get_sample_size(const struct iio_device *dev); +__api __check_ret ssize_t iio_device_get_sample_size(const struct iio_device *dev); /** @brief Get the index of the given channel * @param chn A pointer to an iio_channel structure * @return On success, the index of the specified channel * @return On error, a negative errno code is returned */ -__api __pure long iio_channel_get_index(const struct iio_channel *chn); +__api __check_ret __pure long iio_channel_get_index(const struct iio_channel *chn); /** @brief Get a pointer to a channel's data format structure * @param chn A pointer to an iio_channel structure * @return A pointer to the channel's iio_data_format structure */ -__api __cnst const struct iio_data_format * iio_channel_get_data_format( +__api __check_ret __cnst const struct iio_data_format * iio_channel_get_data_format( const struct iio_channel *chn); @@ -1560,7 +1566,7 @@ __api void iio_channel_convert_inverse(const struct iio_channel *chn, /** @brief Enumerate the debug attributes of the given device * @param dev A pointer to an iio_device structure * @return The number of debug attributes found */ -__api __pure unsigned int iio_device_get_debug_attrs_count( +__api __check_ret __pure unsigned int iio_device_get_debug_attrs_count( const struct iio_device *dev); @@ -1569,7 +1575,7 @@ __api __pure unsigned int iio_device_get_debug_attrs_count( * @param index The index corresponding to the debug attribute * @return On success, a pointer to a static NULL-terminated string * @return If the index is invalid, NULL is returned */ -__api __pure const char * iio_device_get_debug_attr( +__api __check_ret __pure const char * iio_device_get_debug_attr( const struct iio_device *dev, unsigned int index); @@ -1585,7 +1591,7 @@ __api __pure const char * iio_device_get_debug_attr( * attribute. * It can also be used to retrieve the name of a debug attribute as a pointer * to a static string from a dynamically allocated string. */ -__api __pure const char * iio_device_find_debug_attr( +__api __check_ret __pure const char * iio_device_find_debug_attr( const struct iio_device *dev, const char *name); @@ -1611,7 +1617,7 @@ __api __pure const char * iio_device_find_debug_attr( * returned when reading the debug attribute; if positive, it corresponds * to the length of the data read. In that case, the rest of the block contains * the data. */ -__api ssize_t iio_device_debug_attr_read(const struct iio_device *dev, +__api __check_ret ssize_t iio_device_debug_attr_read(const struct iio_device *dev, const char *attr, char *dst, size_t len); @@ -1624,7 +1630,7 @@ __api ssize_t iio_device_debug_attr_read(const struct iio_device *dev, * * NOTE: This function is especially useful when used with the network * backend, as all the debug attributes are read in one single command. */ -__api int iio_device_debug_attr_read_all(struct iio_device *dev, +__api __check_ret int iio_device_debug_attr_read_all(struct iio_device *dev, int (*cb)(struct iio_device *dev, const char *attr, const char *value, size_t len, void *d), void *data); @@ -1649,7 +1655,7 @@ __api int iio_device_debug_attr_read_all(struct iio_device *dev, * network order. If negative, the debug attribute is not written; if positive, * it corresponds to the length of the data to write. In that case, the rest * of the block must contain the data. */ -__api ssize_t iio_device_debug_attr_write(const struct iio_device *dev, +__api __check_ret ssize_t iio_device_debug_attr_write(const struct iio_device *dev, const char *attr, const char *src); @@ -1661,7 +1667,7 @@ __api ssize_t iio_device_debug_attr_write(const struct iio_device *dev, * @param len The number of bytes that should be written * @return On success, the number of bytes written * @return On error, a negative errno code is returned */ -__api ssize_t iio_device_debug_attr_write_raw(const struct iio_device *dev, +__api __check_ret ssize_t iio_device_debug_attr_write_raw(const struct iio_device *dev, const char *attr, const void *src, size_t len); @@ -1674,7 +1680,7 @@ __api ssize_t iio_device_debug_attr_write_raw(const struct iio_device *dev, * * NOTE: This function is especially useful when used with the network * backend, as all the debug attributes are written in one single command. */ -__api int iio_device_debug_attr_write_all(struct iio_device *dev, +__api __check_ret int iio_device_debug_attr_write_all(struct iio_device *dev, ssize_t (*cb)(struct iio_device *dev, const char *attr, void *buf, size_t len, void *d), void *data); @@ -1687,7 +1693,7 @@ __api int iio_device_debug_attr_write_all(struct iio_device *dev, * @param val A pointer to a bool variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_debug_attr_read_bool(const struct iio_device *dev, +__api __check_ret int iio_device_debug_attr_read_bool(const struct iio_device *dev, const char *attr, bool *val); @@ -1698,7 +1704,7 @@ __api int iio_device_debug_attr_read_bool(const struct iio_device *dev, * @param val A pointer to a long long variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_debug_attr_read_longlong(const struct iio_device *dev, +__api __check_ret int iio_device_debug_attr_read_longlong(const struct iio_device *dev, const char *attr, long long *val); @@ -1709,7 +1715,7 @@ __api int iio_device_debug_attr_read_longlong(const struct iio_device *dev, * @param val A pointer to a double variable where the value should be stored * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_debug_attr_read_double(const struct iio_device *dev, +__api __check_ret int iio_device_debug_attr_read_double(const struct iio_device *dev, const char *attr, double *val); @@ -1720,7 +1726,7 @@ __api int iio_device_debug_attr_read_double(const struct iio_device *dev, * @param val A bool value to set the debug attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_debug_attr_write_bool(const struct iio_device *dev, +__api __check_ret int iio_device_debug_attr_write_bool(const struct iio_device *dev, const char *attr, bool val); @@ -1731,7 +1737,7 @@ __api int iio_device_debug_attr_write_bool(const struct iio_device *dev, * @param val A long long value to set the debug attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_debug_attr_write_longlong(const struct iio_device *dev, +__api __check_ret int iio_device_debug_attr_write_longlong(const struct iio_device *dev, const char *attr, long long val); @@ -1742,7 +1748,7 @@ __api int iio_device_debug_attr_write_longlong(const struct iio_device *dev, * @param val A double value to set the debug attribute to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_debug_attr_write_double(const struct iio_device *dev, +__api __check_ret int iio_device_debug_attr_write_double(const struct iio_device *dev, const char *attr, double val); @@ -1758,7 +1764,7 @@ __api int iio_device_debug_attr_write_double(const struct iio_device *dev, * @return On success, 0 is returned, and *chn and *attr are modified. * @return On error, a negative errno code is returned. *chn and *attr are not * modified. */ -__api int iio_device_identify_filename(const struct iio_device *dev, +__api __check_ret int iio_device_identify_filename(const struct iio_device *dev, const char *filename, struct iio_channel **chn, const char **attr); @@ -1769,7 +1775,7 @@ __api int iio_device_identify_filename(const struct iio_device *dev, * @param value The value to set the register to * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_reg_write(struct iio_device *dev, +__api __check_ret int iio_device_reg_write(struct iio_device *dev, uint32_t address, uint32_t value); @@ -1779,7 +1785,7 @@ __api int iio_device_reg_write(struct iio_device *dev, * @param value A pointer to the variable where the value will be written * @return On success, 0 is returned * @return On error, a negative errno code is returned */ -__api int iio_device_reg_read(struct iio_device *dev, +__api __check_ret int iio_device_reg_read(struct iio_device *dev, uint32_t address, uint32_t *value); From b12d0506627e30907c69d5de43977ef17e15e713 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Thu, 20 Feb 2020 20:42:28 -0500 Subject: [PATCH 2/4] tests: check return values on all calls This makes the code check all the missing return values that were skipped in the past, to try to report as many errors as possible. Signed-off-by: Robin Getz --- tests/CMakeLists.txt | 5 +++++ tests/iio_adi_xflow_check.c | 14 ++++++++++--- tests/iio_attr.c | 17 ++++++++++++---- tests/iio_info.c | 27 ++++++++++++++++++++----- tests/iio_readdev.c | 39 +++++++++++++++++++++++++++++++------ tests/iio_writedev.c | 39 +++++++++++++++++++++++++++++++------ 6 files changed, 117 insertions(+), 24 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 545f0304c..072d0275c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,6 +22,11 @@ if (WIN32) set(LIBIIO_RC ${CMAKE_CURRENT_BINARY_DIR}/properties.rc) configure_file(../properties.rc.cmakein ${LIBIIO_RC} @ONLY) endif() + +if (CMAKE_COMPILER_IS_GNUCC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DIIO_CHECK_RET") +endif() + add_executable(iio_genxml iio_genxml.c ${GETOPT_C_FILE} ${LIBIIO_RC}) add_executable(iio_info iio_info.c ${GETOPT_C_FILE} ${LIBIIO_RC}) add_executable(iio_attr iio_attr.c gen_code.c ${GETOPT_C_FILE} ${LIBIIO_RC}) diff --git a/tests/iio_adi_xflow_check.c b/tests/iio_adi_xflow_check.c index 569895d12..ee9aeea5c 100644 --- a/tests/iio_adi_xflow_check.c +++ b/tests/iio_adi_xflow_check.c @@ -126,7 +126,11 @@ static void *monitor_thread_fn(void *data) sleep(1); /* Clear all status bits */ - iio_device_reg_write(dev, 0x80000088, 0x6); + ret = iio_device_reg_write(dev, 0x80000088, 0x6); + if (ret) { + fprintf(stderr, "Failed to clearn DMA status register: %s\n", + strerror(-ret)); + } while (app_running) { ret = iio_device_reg_read(dev, 0x80000088, &val); @@ -145,8 +149,12 @@ static void *monitor_thread_fn(void *data) } /* Clear bits */ - if (val) - iio_device_reg_write(dev, 0x80000088, val); + if (val) { + ret = iio_device_reg_write(dev, 0x80000088, val); + if (ret) + fprintf(stderr, "Failed to clearn DMA status register: %s\n", + strerror(-ret)); + } sleep(1); } diff --git a/tests/iio_attr.c b/tests/iio_attr.c index 70f11d9fb..cec667ce4 100644 --- a/tests/iio_attr.c +++ b/tests/iio_attr.c @@ -650,11 +650,20 @@ int main(int argc, char **argv) for (i = 0; i < nb_ctx_attrs; i++) { const char *key, *value; + ssize_t ret; - iio_context_get_attr(ctx, i, &key, &value); - if (!attr_index || str_match(key, argv[attr_index], ignore_case)) { - printf("%s: %s\n", key, value); - gen_context_attr(key); + ret = iio_context_get_attr(ctx, i, &key, &value); + if (!ret) { + if (!attr_index || str_match(key, argv[attr_index], ignore_case)) { + printf("%s: %s\n", key, value); + gen_context_attr(key); + } + } else { + char *buf = xmalloc(BUF_SIZE); + iio_strerror(errno, buf, BUF_SIZE); + fprintf(stderr, "Unable to get context attributes: %s (%zd)\n", + buf, ret); + free(buf); } } } diff --git a/tests/iio_info.c b/tests/iio_info.c index 20af48319..3222d310b 100644 --- a/tests/iio_info.c +++ b/tests/iio_info.c @@ -106,7 +106,9 @@ static void scan(void) ret = iio_scan_context_get_info_list(ctx, &info); if (ret < 0) { - fprintf(stderr, "Unable to scan: %li\n", (long) ret); + char err_str[1024]; + iio_strerror(-ret, err_str, sizeof(err_str)); + fprintf(stderr, "Unable to scan: %s (%zd)\n", err_str, ret); goto err_free_ctx; } @@ -295,8 +297,11 @@ int main(int argc, char **argv) if (!ret) printf("Backend version: %u.%u (git tag: %s)\n", major, minor, git_tag); - else - fprintf(stderr, "Unable to get backend version: %i\n", ret); + else { + char err_str[1024]; + iio_strerror(-ret, err_str, sizeof(err_str)); + fprintf(stderr, "Unable to get backend version: %s (%i)\n", err_str, ret); + } printf("Backend description string: %s\n", iio_context_get_description(ctx)); @@ -308,8 +313,15 @@ int main(int argc, char **argv) for (i = 0; i < nb_ctx_attrs; i++) { const char *key, *value; - iio_context_get_attr(ctx, i, &key, &value); - printf("\t%s: %s\n", key, value); + ret = iio_context_get_attr(ctx, i, &key, &value); + if (ret == 0) + printf("\t%s: %s\n", key, value); + else { + char err_str[1024]; + iio_strerror(-ret, err_str, sizeof(err_str)); + fprintf(stderr, "\tUnable to read IIO context attributes: %s (%i)\n", + err_str, ret); + } } unsigned int nb_devices = iio_context_get_devices_count(ctx); @@ -467,6 +479,11 @@ int main(int argc, char **argv) iio_device_get_id(trig), name ? name : ""); } + } else if (ret == -ENOENT) { + printf("\t\tNo trigger on this device\n"); + } else if (ret < 0) { + iio_strerror(-ret, buf, BUF_SIZE); + printf("ERROR: checking for trigger : %s (%i)\n", buf, ret); } } diff --git a/tests/iio_readdev.c b/tests/iio_readdev.c index 7bc7aac6f..ac9640aa9 100644 --- a/tests/iio_readdev.c +++ b/tests/iio_readdev.c @@ -261,6 +261,7 @@ int main(int argc, char **argv) size_t sample_size; int timeout = -1; bool scan_for_context = false; + ssize_t ret; while ((c = getopt_long(argc, argv, "+hn:u:t:b:s:T:a", options, &option_index)) != -1) { @@ -316,8 +317,15 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - if (timeout >= 0) - iio_context_set_timeout(ctx, timeout); + if (timeout >= 0) { + ret = iio_context_set_timeout(ctx, timeout); + if (ret < 0) { + char err_str[1024]; + iio_strerror(-ret, err_str, sizeof(err_str)); + fprintf(stderr, "IIO contexts set timeout failed : %s (%zd)\n", + err_str, ret); + } + } dev = iio_context_find_device(ctx, argv[optind]); if (!dev) { @@ -346,11 +354,24 @@ int main(int argc, char **argv) * fail gracefully to remain compatible. */ if (iio_device_attr_write_longlong(trigger, - "sampling_frequency", DEFAULT_FREQ_HZ) < 0) - iio_device_attr_write_longlong(trigger, + "sampling_frequency", DEFAULT_FREQ_HZ) < 0) { + ret = iio_device_attr_write_longlong(trigger, "frequency", DEFAULT_FREQ_HZ); + if (ret < 0) { + char buf[256]; + iio_strerror(-ret, buf, sizeof(buf)); + fprintf(stderr, "sample rate not set : %s (%zd)\n", + buf, ret); + } + } - iio_device_set_trigger(dev, trigger); + ret = iio_device_set_trigger(dev, trigger); + if (ret < 0) { + char buf[256]; + iio_strerror(-ret, buf, sizeof(buf)); + fprintf(stderr, "set triffer failed : %s (%zd)\n", + buf, ret); + } } nb_channels = iio_device_get_channels_count(dev); @@ -427,7 +448,13 @@ int main(int argc, char **argv) quit_all(EXIT_SUCCESS); } } else { - iio_buffer_foreach_sample(buffer, print_sample, NULL); + ret = iio_buffer_foreach_sample(buffer, print_sample, NULL); + if (ret < 0) { + char buf[256]; + iio_strerror(-ret, buf, sizeof(buf)); + fprintf(stderr, "buffer processing failed : %s (%d)\n", + buf, ret); + } } } diff --git a/tests/iio_writedev.c b/tests/iio_writedev.c index b91bfa1c2..b2047dd0d 100644 --- a/tests/iio_writedev.c +++ b/tests/iio_writedev.c @@ -271,6 +271,7 @@ int main(int argc, char **argv) int timeout = -1; bool scan_for_context = false; bool cyclic_buffer = false; + ssize_t ret; while ((c = getopt_long(argc, argv, "+hn:u:t:b:s:T:ac", options, &option_index)) != -1) { @@ -329,8 +330,15 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - if (timeout >= 0) - iio_context_set_timeout(ctx, timeout); + if (timeout >= 0) { + ret = iio_context_set_timeout(ctx, timeout); + if (ret < 0) { + char err_str[1024]; + iio_strerror(-ret, err_str, sizeof(err_str)); + fprintf(stderr, "IIO contexts set timeout failed : %s (%zd)\n", + err_str, ret); + } + } dev = iio_context_find_device(ctx, argv[optind]); if (!dev) { @@ -359,11 +367,24 @@ int main(int argc, char **argv) * fail gracefully to remain compatible. */ if (iio_device_attr_write_longlong(trigger, - "sampling_frequency", DEFAULT_FREQ_HZ) < 0) - iio_device_attr_write_longlong(trigger, + "sampling_frequency", DEFAULT_FREQ_HZ) < 0) { + ret = iio_device_attr_write_longlong(trigger, "frequency", DEFAULT_FREQ_HZ); + if (ret < 0) { + char buf[256]; + iio_strerror(-ret, buf, sizeof(buf)); + fprintf(stderr, "sample rate not set : %s (%zd)\n", + buf, ret); + } + } - iio_device_set_trigger(dev, trigger); + ret = iio_device_set_trigger(dev, trigger); + if (ret < 0) { + char buf[256]; + iio_strerror(-ret, buf, sizeof(buf)); + fprintf(stderr, "set triffer failed : %s (%zd)\n", + buf, ret); + } } nb_channels = iio_device_get_channels_count(dev); @@ -426,7 +447,13 @@ int main(int argc, char **argv) quit_all(EXIT_SUCCESS); } } else { - iio_buffer_foreach_sample(buffer, read_sample, NULL); + ret = iio_buffer_foreach_sample(buffer, read_sample, NULL); + if (ret < 0) { + char buf[256]; + iio_strerror(-ret, buf, sizeof(buf)); + fprintf(stderr, "buffer processing failed : %s (%zd)\n", + buf, ret); + } } int ret = iio_buffer_push(buffer); From 303747685c20f0545aa9984c1ae1dcc0aee1a77b Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Fri, 21 Feb 2020 12:54:39 -0500 Subject: [PATCH 3/4] add new option and description to man page Signed-off-by: Robin Getz --- man/make_man.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/man/make_man.sh b/man/make_man.sh index 92528597d..00832744f 100755 --- a/man/make_man.sh +++ b/man/make_man.sh @@ -46,6 +46,22 @@ subsystem and devices .sp cc file.c .B -liio +.SH OPTIONS +The define +.B +IIO_CHECK_REG +will warn if return values are not checked. Most +.B +libiio +functions, if/when a failure occurs will return a negative error number. +this warning will ensure these error numbers are looked at. There is +nothing more frustraining than calling a function, debugging some hardware, +and then eventually realizing there was a typo in an attribute name. +This option will force libraries users to at least capture the return value. +.sp +cc file.c +.B -DIIO_CHECK_REG -liio + .SH DESCRIPTION .I libiio is a library used to interface to the From 34f3a996424b320217159664b0edb4190c812707 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Tue, 10 Mar 2020 00:04:30 -0400 Subject: [PATCH 4/4] examples: ensure all examples compile with new return checking option This sets the-DIIO_CHECK_RET flag in the Makefile, and fixes the issues that were pointed out. Signed-off-by: Robin Getz --- examples/Makefile | 2 +- examples/dummy-iiostream.c | 23 +++++++++++++++++++---- examples/iio-monitor.c | 38 ++++++++++++++++++++++++++++++-------- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 266ff8fa1..4f23d2b39 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -16,7 +16,7 @@ TARGETS := ad9361-iiostream ad9371-iiostream adrv9009-iiostream dummy-iiostream iio-monitor -CFLAGS = -Wall +CFLAGS = -Wall -DIIO_CHECK_RET UNAME_S := $(shell uname -s) diff --git a/examples/dummy-iiostream.c b/examples/dummy-iiostream.c index 49ced3210..5dedafd68 100644 --- a/examples/dummy-iiostream.c +++ b/examples/dummy-iiostream.c @@ -122,13 +122,22 @@ static bool has_repeat; /* cleanup and exit */ static void shutdown() { + int ret; + if (channels) { free(channels); } printf("* Destroying buffers\n"); if (rxbuf) { iio_buffer_destroy(rxbuf); } printf("* Disassociate trigger\n"); - if (dev) { iio_device_set_trigger(dev, NULL); } + if (dev) { + ret = iio_device_set_trigger(dev, NULL); + if (ret < 0) { + char buf[256]; + iio_strerror(-ret, buf, sizeof(buf)); + fprintf(stderr, "%s (%d) while Disassociate trigger\n", buf, ret); + } + } printf("* Destroying context\n"); if (ctx) { iio_context_destroy(ctx); } @@ -333,11 +342,17 @@ int main (int argc, char **argv) printf("\n"); break; - case SAMPLE_CALLBACK: - iio_buffer_foreach_sample(rxbuf, sample_cb, NULL); + case SAMPLE_CALLBACK: { + int ret; + ret = iio_buffer_foreach_sample(rxbuf, sample_cb, NULL); + if (ret < 0) { + char buf[256]; + iio_strerror(-ret, buf, sizeof(buf)); + fprintf(stderr, "%s (%d) while processing buffer\n", buf, ret); + } printf("\n"); break; - + } case CHANNEL_READ_RAW: case CHANNEL_READ: for (int i = 0; i < channel_count; ++i) { diff --git a/examples/iio-monitor.c b/examples/iio-monitor.c index a82b44aab..78057d250 100644 --- a/examples/iio-monitor.c +++ b/examples/iio-monitor.c @@ -63,30 +63,52 @@ static bool is_valid_channel(struct iio_channel *chn) channel_has_attr(chn, "input")); } +static void err_str(int ret) +{ + char buf[256]; + iio_strerror(-ret, buf, sizeof(buf)); + fprintf(stderr, "Error during read: %s (%d)\n", buf, ret); +} + static double get_channel_value(struct iio_channel *chn) { char *old_locale; char buf[1024]; double val; + int ret; old_locale = strdup(setlocale(LC_NUMERIC, NULL)); setlocale(LC_NUMERIC, "C"); if (channel_has_attr(chn, "input")) { - iio_channel_attr_read(chn, "input", buf, sizeof(buf)); - val = strtod(buf, NULL); + ret = iio_channel_attr_read(chn, "input", buf, sizeof(buf)); + if (ret < 0) { + err_str(ret); + val = 0; + } else + val = strtod(buf, NULL); } else { - iio_channel_attr_read(chn, "raw", buf, sizeof(buf)); - val = strtod(buf, NULL); + ret = iio_channel_attr_read(chn, "raw", buf, sizeof(buf)); + if (ret < 0) { + err_str(ret); + val = 0; + } else + val = strtod(buf, NULL); if (channel_has_attr(chn, "offset")) { - iio_channel_attr_read(chn, "offset", buf, sizeof(buf)); - val += strtod(buf, NULL); + ret = iio_channel_attr_read(chn, "offset", buf, sizeof(buf)); + if (ret < 0) + err_str(ret); + else + val += strtod(buf, NULL); } if (channel_has_attr(chn, "scale")) { - iio_channel_attr_read(chn, "scale", buf, sizeof(buf)); - val *= strtod(buf, NULL); + ret = iio_channel_attr_read(chn, "scale", buf, sizeof(buf)); + if (ret < 0) + err_str(ret); + else + val *= strtod(buf, NULL); } }