Skip to content

Commit

Permalink
Merge pull request #175 from analogdevicesinc/sort
Browse files Browse the repository at this point in the history
local: Sort devices, channels and attributes
  • Loading branch information
mhennerich authored Oct 22, 2018
2 parents 256a80a + 53bfb03 commit 72feae0
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 72feae0

Please sign in to comment.