1 /*
2  * libiio - Library for interfacing industrial I/O (IIO) devices
3  *
4  * Copyright (C) 2018 Analog Devices, Inc.
5  * Author: Robin Getz <robin.getz@analog.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * */
18 
19 #include "iio-private.h"
20 #include <string.h>
21 
22 /* These are a few functions to do sorting via qsort for various
23  * iio structures. For more info, see the qsort(3) man page.
24  *
25  * The qsort comparison function must return an integer less than, equal to,
26  * or greater than zero if the first argument is considered to be
27  * respectively less than, equal to, or greater than the second. If two
28  * members compare as equal, their order in the sort order is undefined.
29  *
30  * If the structures are updated, the compare functions may
31  * need to be updated.
32  *
33  * The actual arguments to these function are "pointers to
34  * pointers to char", but strcmp(3) arguments are "pointers
35  * to char", hence the cast plus dereference
36  */
37 
iio_channel_compare(const void * p1,const void * p2)38 int iio_channel_compare(const void *p1, const void *p2)
39 {
40 	const struct iio_channel *tmp1 = *(struct iio_channel **)p1;
41 	const struct iio_channel *tmp2 = *(struct iio_channel **)p2;
42 
43 	/* make sure buffer enabled channels are first */
44 	if (iio_channel_is_scan_element(tmp1) && !iio_channel_is_scan_element(tmp2))
45 		return -1;
46 	if (!iio_channel_is_scan_element(tmp1) && iio_channel_is_scan_element(tmp2))
47 		return 1;
48 	/* and sort them by index */
49 	if (iio_channel_is_scan_element(tmp1) && iio_channel_is_scan_element(tmp2)){
50 		if (iio_channel_get_index(tmp1) > iio_channel_get_index(tmp2))
51 			return 1;
52 		return -1;
53 	}
54 	/* otherwise, if the ID is the same, input channels first */
55 	if (strcmp(tmp1->id, tmp2->id) == 0)
56 		return !iio_channel_is_output(tmp1);
57 
58 	/* finally by ID */
59 	return strcmp(tmp1->id, tmp2->id);
60 }
61 
iio_channel_attr_compare(const void * p1,const void * p2)62 int iio_channel_attr_compare(const void *p1, const void *p2)
63 {
64 	const struct iio_channel_attr *tmp1 = (struct iio_channel_attr *)p1;
65 	const struct iio_channel_attr *tmp2 = (struct iio_channel_attr *)p2;
66 	/* qsort channel attributes by name */
67 	return strcmp(tmp1->name, tmp2->name);
68 }
69 
iio_device_compare(const void * p1,const void * p2)70 int iio_device_compare(const void *p1, const void *p2)
71 {
72 	const struct iio_device *tmp1 = *(struct iio_device **)p1;
73 	const struct iio_device *tmp2 = *(struct iio_device **)p2;
74 	/* qsort devices by ID */
75 	return strcmp(tmp1->id, tmp2->id);
76 }
77 
iio_device_attr_compare(const void * p1,const void * p2)78 int iio_device_attr_compare(const void *p1, const void *p2)
79 {
80 	const char *tmp1 = *(const char **)p1;
81 	const char *tmp2 = *(const char **)p2;
82 	/* qsort device attributes by name */
83 	return strcmp(tmp1, tmp2);
84 }
85 
iio_buffer_attr_compare(const void * p1,const void * p2)86 int iio_buffer_attr_compare(const void *p1, const void *p2)
87 {
88 	const char *tmp1 = *(const char **)p1;
89 	const char *tmp2 = *(const char **)p2;
90 	/* qsort buffer attributes by name */
91 	return strcmp(tmp1, tmp2);
92 }
93 
94