shell: refactor device_name_get implementation

Several shell modules use cloned code to iterate over all devices and
identify the nth instance that meets some criteria.  The code was
repetitive and included various errors.  Abstract to a helper function
that performs the check consistently.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
Peter Bigot 2020-06-22 09:56:19 -05:00 committed by Carles Cufí
commit a538dcd8f8
5 changed files with 51 additions and 43 deletions

View file

@ -225,24 +225,12 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get);
static void device_name_get(size_t idx, struct shell_static_entry *entry)
{
int device_idx = 0;
struct device *dev;
struct device *dev = shell_device_lookup(idx, NULL);
entry->syntax = NULL;
entry->syntax = (dev != NULL) ? dev->name : NULL;
entry->handler = NULL;
entry->help = NULL;
entry->subcmd = &dsub_device_name;
for (dev = __device_start; dev != __device_end; dev++) {
if ((dev->driver_api != NULL) &&
strcmp(dev->name, "") && (dev->name != NULL)) {
if (idx == device_idx) {
entry->syntax = dev->name;
break;
}
device_idx++;
}
}
}
SHELL_STATIC_SUBCMD_SET_CREATE(flash_cmds,

View file

@ -224,25 +224,12 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get);
static void device_name_get(size_t idx, struct shell_static_entry *entry)
{
int device_idx = 0;
struct device *dev;
struct device *dev = shell_device_lookup(idx, I2C_DEVICE_PREFIX);
entry->syntax = NULL;
entry->syntax = (dev != NULL) ? dev->name : NULL;
entry->handler = NULL;
entry->help = NULL;
entry->subcmd = &dsub_device_name;
for (dev = __device_start; dev != __device_end; dev++) {
if ((dev->driver_api != NULL) && (dev->name != NULL) &&
strstr(dev->name, I2C_DEVICE_PREFIX) != NULL &&
strcmp(dev->name, "")) {
if (idx == device_idx) {
entry->syntax = dev->name;
break;
}
device_idx++;
}
}
}
SHELL_STATIC_SUBCMD_SET_CREATE(sub_i2c_cmds,

View file

@ -173,24 +173,12 @@ SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get);
static void device_name_get(size_t idx, struct shell_static_entry *entry)
{
int device_idx = 0;
struct device *dev;
struct device *dev = shell_device_lookup(idx, NULL);
entry->syntax = NULL;
entry->syntax = (dev != NULL) ? dev->name : NULL;
entry->handler = NULL;
entry->help = NULL;
entry->subcmd = &dsub_channel_name;
for (dev = __device_start; dev != __device_end; dev++) {
if ((dev->driver_api != NULL) &&
strcmp(dev->name, "") && (dev->name != NULL)) {
if (idx == device_idx) {
entry->syntax = dev->name;
break;
}
device_idx++;
}
}
}
SHELL_STATIC_SUBCMD_SET_CREATE(sub_sensor,

View file

@ -104,6 +104,24 @@ struct shell_static_args {
uint8_t optional; /*!< Number of optional arguments. */
};
/**
* @brief Get by index a device that matches .
*
* This can be used, for example, to identify I2C_1 as the second I2C
* device.
*
* Devices that failed to initialize or do not have a non-empty name
* are excluded from the candidates for a match.
*
* @param idx the device number starting from zero.
*
* @param prefix optional name prefix used to restrict candidate
* devices. Indexing is done relative to devices with names that
* start with this text. Pass null if no prefix match is required.
*/
struct device *shell_device_lookup(size_t idx,
const char *prefix);
/**
* @brief Shell command handler prototype.
*

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <ctype.h>
#include <device.h>
#include "shell_utils.h"
#include "shell_wildcard.h"
@ -459,3 +460,29 @@ void shell_cmd_trim(const struct shell *shell)
buffer_trim(shell->ctx->cmd_buff, &shell->ctx->cmd_buff_len);
shell->ctx->cmd_buff_pos = shell->ctx->cmd_buff_len;
}
struct device *shell_device_lookup(size_t idx,
const char *prefix)
{
size_t match_idx = 0;
struct device *dev;
size_t len = z_device_get_all_static(&dev);
struct device *dev_end = dev + len;
while (dev < dev_end) {
if ((dev->driver_api != NULL)
&& (dev->name != NULL)
&& (strlen(dev->name) != 0)
&& ((prefix == NULL)
|| (strncmp(prefix, dev->name,
strlen(prefix)) == 0))) {
if (match_idx == idx) {
return dev;
}
++match_idx;
}
++dev;
}
return NULL;
}