Skip to content

Commit

Permalink
local: Sort devices, channels and attributes when adding them.
Browse files Browse the repository at this point in the history
In this way, other iio utilities will output information in an easy to
read/compare way.

This has no functionality difference, except to add a small negative
performance, but it makes the output of iio_attr and iio_info, much
easier to track by hand.

Signed-off-by: Robin Getz <[email protected]>
  • Loading branch information
rgetz committed Oct 19, 2018
1 parent 6ecff5d commit 53bfb03
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 23 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ if (ENABLE_IPV6)
endif()
endif()

set(LIBIIO_CFILES backend.c channel.c device.c context.c buffer.c utilities.c scan.c)
set(LIBIIO_CFILES backend.c channel.c device.c context.c buffer.c utilities.c scan.c sort.c)
set(LIBIIO_HEADERS iio.h)

add_definitions(-D_POSIX_C_SOURCE=200809L -D__XSI_VISIBLE=500 -DLIBIIO_EXPORTS=1)
Expand Down
24 changes: 3 additions & 21 deletions context.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "debug.h"
#include "iio-config.h"
#include "iio-private.h"
#include "sort.h"

#include <errno.h>
#include <string.h>
Expand Down Expand Up @@ -201,30 +202,11 @@ struct iio_device * iio_context_find_device(const struct iio_context *ctx,

static void reorder_channels(struct iio_device *dev)
{
bool found;
unsigned int i;

/* Reorder channels by index */
do {
found = false;
for (i = 1; i < dev->nb_channels; i++) {
struct iio_channel **channels = dev->channels;
long ch1 = channels[i - 1]->index;
long ch2 = channels[i]->index;

if (ch1 == ch2 && ch1 >= 0) {
ch1 = channels[i - 1]->format.shift;
ch2 = channels[i]->format.shift;
}

if (ch2 >= 0 && ((ch1 > ch2) || ch1 < 0)) {
struct iio_channel *bak = channels[i];
channels[i] = channels[i - 1];
channels[i - 1] = bak;
found = true;
}
}
} while (found);
qsort(dev->channels, dev->nb_channels, sizeof(struct iio_channel *),
qsort_iio_channel);

for (i = 0; i < dev->nb_channels; i++)
dev->channels[i]->number = i;
Expand Down
5 changes: 5 additions & 0 deletions iio-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ struct iio_backend_ops {
int (*set_timeout)(struct iio_context *ctx, unsigned int timeout);
};

/*
* If these structures are updated, the qsort functions defined in sort.c
* may need to be updated.
*/

struct iio_context_pdata;
struct iio_device_pdata;
struct iio_channel_pdata;
Expand Down
17 changes: 16 additions & 1 deletion local.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "debug.h"
#include "iio-private.h"
#include "sort.h"

#include <dirent.h>
#include <errno.h>
Expand Down Expand Up @@ -1359,7 +1360,9 @@ static int add_channel_to_device(struct iio_device *dev,

channels[dev->nb_channels++] = chn;
dev->channels = channels;
DEBUG("Added channel \'%s\' to device \'%s\'\n", chn->id, dev->id);
DEBUG("Added %s channel \'%s\' to device \'%s\'\n",
chn->is_output ? "output" : "input", chn->id, dev->id);

return 0;
}

Expand Down Expand Up @@ -1708,6 +1711,9 @@ static int add_buffer_attributes(struct iio_device *dev, const char *devpath)
int ret = foreach_in_dir(dev, buf, false, add_buffer_attr);
if (ret < 0)
return ret;

qsort(dev->buffer_attrs, dev->nb_buffer_attrs, sizeof(char *),
qsort_iio_buffer_attr);
}

return 0;
Expand Down Expand Up @@ -1761,12 +1767,18 @@ static int create_device(void *d, const char *path)
free_protected_attrs(chn);
if (ret < 0)
goto err_free_scan_elements;

qsort(chn->attrs, chn->nb_attrs, sizeof(struct iio_channel_attr),
qsort_iio_channel_attr);
}

ret = detect_and_move_global_attrs(dev);
if (ret < 0)
goto err_free_device;

qsort(dev->attrs, dev->nb_attrs, sizeof(char *),
qsort_iio_device_attr);

dev->words = (dev->nb_channels + 31) / 32;
if (dev->words) {
mask = calloc(dev->words, sizeof(*mask));
Expand Down Expand Up @@ -1990,6 +2002,9 @@ struct iio_context * local_create_context(void)
if (ret < 0)
goto err_context_destroy;

qsort(ctx->devices, ctx->nb_devices, sizeof(struct iio_device *),
qsort_iio_device);

foreach_in_dir(ctx, "/sys/kernel/debug/iio", true, add_debug);

init_scan_elements(ctx);
Expand Down
87 changes: 87 additions & 0 deletions sort.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* libiio - Library for interfacing industrial I/O (IIO) devices
*
* Copyright (C) 2018 Analog Devices, Inc.
* Author: Robin Getz <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* */

#include "iio-private.h"
#include <string.h>

/* These are a few functions to do sorting for various
* iio structures. For more info, see the qsort(3) man page.
* If the structures are updated, the sort functions may
* need to be updated.
*
* The actual arguments to these function are "pointers to
* pointers to char", but strcmp(3) arguments are "pointers
* to char", hence the cast plus dereference
*/

int qsort_iio_channel(const void *p1, const void *p2)
{
const struct iio_channel *tmp1 = *(struct iio_channel **)p1;
const struct iio_channel *tmp2 = *(struct iio_channel **)p2;

/* make sure buffer enabled channels are first */
if (iio_channel_is_scan_element(tmp1) && !iio_channel_is_scan_element(tmp2))
return -1;
if (!iio_channel_is_scan_element(tmp1) && iio_channel_is_scan_element(tmp2))
return 1;
/* and sort them by index */
if (iio_channel_is_scan_element(tmp1) && iio_channel_is_scan_element(tmp2)){
if (iio_channel_get_index(tmp1) > iio_channel_get_index(tmp2))
return 1;
return -1;
}
/* otherwise, if the ID is the same, input channels first */
if (strcmp(tmp1->id, tmp2->id) == 0)
return !iio_channel_is_output(tmp1);

/* finally by ID */
return strcmp(tmp1->id, tmp2->id);
}

int qsort_iio_channel_attr(const void *p1, const void *p2)
{
const struct iio_channel_attr *tmp1 = (struct iio_channel_attr *)p1;
const struct iio_channel_attr *tmp2 = (struct iio_channel_attr *)p2;
/* qsort channel attributes by name */
return strcmp(tmp1->name, tmp2->name);
}

int qsort_iio_device(const void *p1, const void *p2)
{
const struct iio_device *tmp1 = *(struct iio_device **)p1;
const struct iio_device *tmp2 = *(struct iio_device **)p2;
/* qsort devices by ID */
return strcmp(tmp1->id, tmp2->id);
}

int qsort_iio_device_attr(const void *p1, const void *p2)
{
const char *tmp1 = *(const char **)p1;
const char *tmp2 = *(const char **)p2;
/* qsort device attributes by name */
return strcmp(tmp1, tmp2);
}

int qsort_iio_buffer_attr(const void *p1, const void *p2)
{
const char *tmp1 = *(const char **)p1;
const char *tmp2 = *(const char **)p2;
/* qsort buffer attributes by name */
return strcmp(tmp1, tmp2);
}

28 changes: 28 additions & 0 deletions sort.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* libiio - Library for interfacing industrial I/O (IIO) devices
*
* Copyright (C) 2018 Analog Devices, Inc.
* Author: Robin Getz <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* */

#ifndef __IIO_QSORT_H__
#define __IIO_QSORT_H__

int qsort_iio_channel(const void *p1, const void *p2);
int qsort_iio_channel_attr(const void *p1, const void *p2);
int qsort_iio_device(const void *p1, const void *p2);
int qsort_iio_device_attr(const void *p1, const void *p2);
int qsort_iio_buffer_attr(const void *p1, const void *p2);

#endif /* __IIO_QSORT_H__ */

0 comments on commit 53bfb03

Please sign in to comment.