30 diff = *((
double *)b) - *((
double *)a);
31 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
46 diff = fabs(*((
double *)b)) - fabs(*((
double *)a));
47 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
62 diff = *((
double *)b) - *((
double *)a);
63 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
78 diff = fabs(*((
double *)b)) - fabs(*((
double *)a));
79 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
82void double_copy(
void *a,
void *b) {
84 *((
double *)a) = *((
double *)b);
87int float_cmpasc(
const void *a,
const void *b) {
90 diff = *((
float *)b) - *((
float *)a);
91 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
94int float_abs_cmpasc(
const void *a,
const void *b) {
97 diff = fabsf(*((
float *)b)) - fabsf(*((
float *)a));
98 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
101int float_cmpdes(
const void *a,
const void *b) {
104 diff = *((
float *)b) - *((
float *)a);
105 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
108int float_abs_cmpdes(
const void *a,
const void *b) {
111 diff = fabsf(*((
float *)b)) - fabsf(*((
float *)a));
112 return (diff > 0 ? 1 : (diff < 0 ? -1 : 0));
115void float_copy(
void *a,
void *b) {
116 *((
float *)a) = *((
float *)b);
130 diff = *((int32_t *)b) - *((int32_t *)a);
131 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
145 diff = labs(*((int32_t *)b)) - labs(*((int32_t *)a));
146 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
149int long_cmpdes(
const void *a,
const void *b) {
151 diff = *((
long *)a) - *((
long *)b);
152 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
155int long_abs_cmpdes(
const void *a,
const void *b) {
157 diff = labs(*((
long *)a)) - labs(*((
long *)b));
158 return (diff < 0 ? 1 : (diff > 0 ? -1 : 0));
161void long_copy(
void *a,
void *b) {
162 *((
long *)a) = *((
long *)b);
175 return (strcmp(*((
char **)a), *((
char **)b)));
178int string_cmpdes(
const void *a,
const void *b) {
179 return (strcmp(*((
char **)b), *((
char **)a)));
192 if ((
long)strlen(*((
char **)a)) >= (
long)strlen(*((
char **)b)))
195 cp_str(((
char **)a), *((
char **)b));
210int unique(
void *base,
size_t n_items,
size_t size,
211 int (*compare)(
const void *a,
const void *b),
212 void (*copy)(
void *a,
void *b)) {
215 for (i = 0; i < n_items - 1; i++) {
216 if ((*compare)((
char *)base + i * size, (
char *)base + (i + 1) * size) == 0) {
217 for (j = i + 1; j < n_items - 1; j++)
218 (*copy)((
char *)base + j * size, (
char *)base + (j + 1) * size);
226static int (*item_compare)(
const void *a,
const void *b);
227static int column_to_compare;
228static int size_of_element;
229static int number_of_columns;
245 int (*compare)(
const void *a,
const void *b)) {
246 if ((column_to_compare = sort_by_column) >= (number_of_columns = n_columns))
247 bomb(
"column out of range in set_up_row_sort()", NULL);
248 size_of_element = element_size;
249 if (!(item_compare = compare))
250 bomb(
"null function pointer in set_up_row_sort()", NULL);
266 return ((*item_compare)(*a + size_of_element * column_to_compare,
267 *b + size_of_element * column_to_compare));
270void row_copy(
void *av,
void *bv) {
280static long orderIndices;
294 if ((value = strcmp((*(
const KEYED_INDEX *)ki1).stringKey, (*(
const KEYED_INDEX *)ki2).stringKey)))
297 return (*(
const KEYED_INDEX *)ki1).rowIndex - (*(
const KEYED_INDEX *)ki2).rowIndex;
313 if ((diff = (*(
const KEYED_INDEX *)ki1).doubleKey - (*(
const KEYED_INDEX *)ki2).doubleKey)) {
319 return (*(
const KEYED_INDEX *)ki1).rowIndex - (*(
const KEYED_INDEX *)ki2).rowIndex;
333 return strcmp((*(KEYED_EQUIVALENT *)kg1).equivalent[0]->stringKey, (*(KEYED_EQUIVALENT *)kg2).equivalent[0]->stringKey);
347 if ((diff = (*(KEYED_EQUIVALENT *)kg1).equivalent[0]->doubleKey - (*(KEYED_EQUIVALENT *)kg2).equivalent[0]->doubleKey)) {
367 KEYED_EQUIVALENT **keyedEquiv = NULL;
368 static KEYED_INDEX *keyedIndex = NULL;
376 if (!(keyedIndex = (KEYED_INDEX *)malloc(
sizeof(*keyedIndex) * points)) ||
377 !(keyedEquiv = (KEYED_EQUIVALENT **)malloc(
sizeof(*keyedEquiv) * points))) {
378 fprintf(stderr,
"memory allocation failure");
384 for (i1 = 0; i1 < points; i1++) {
385 keyedIndex[i1].stringKey =
string[i1];
386 keyedIndex[i1].rowIndex = i1;
391 for (iEquiv = i1 = 0; i1 < points; iEquiv++) {
392 for (i2 = i1 + 1; i2 < points; i2++) {
396 if (!(keyedEquiv[iEquiv] = (KEYED_EQUIVALENT *)malloc(
sizeof(KEYED_EQUIVALENT))) ||
397 !(keyedEquiv[iEquiv]->equivalent = (KEYED_INDEX **)malloc(
sizeof(KEYED_INDEX *) * (i2 - i1)))) {
398 fprintf(stderr,
"memory allocation failure");
401 keyedEquiv[iEquiv]->equivalents = i2 - i1;
402 keyedEquiv[iEquiv]->nextIndex = 0;
403 for (j = 0; i1 < i2; i1++, j++)
404 keyedEquiv[iEquiv]->equivalent[j] = keyedIndex + i1;
409 for (i1 = 0; i1 < points; i1++) {
410 keyedIndex[i1].doubleKey = value[i1];
411 keyedIndex[i1].rowIndex = i1;
416 for (iEquiv = i1 = 0; i1 < points; iEquiv++) {
417 for (i2 = i1 + 1; i2 < points; i2++) {
421 if (!(keyedEquiv[iEquiv] = (KEYED_EQUIVALENT *)malloc(
sizeof(KEYED_EQUIVALENT))) ||
422 !(keyedEquiv[iEquiv]->equivalent = (KEYED_INDEX **)malloc(
sizeof(KEYED_INDEX *) * (i2 - i1)))) {
423 fprintf(stderr,
"memory allocation failure");
426 keyedEquiv[iEquiv]->equivalents = i2 - i1;
427 keyedEquiv[iEquiv]->nextIndex = 0;
428 for (j = 0; i1 < i2; i1++, j++)
429 keyedEquiv[iEquiv]->equivalent[j] = keyedIndex + i1;
449 void *searchKeyData,
long reuse) {
450 static KEYED_EQUIVALENT *searchKey = NULL;
451 static KEYED_INDEX keyedIndex;
455 searchKey = (KEYED_EQUIVALENT *)malloc(
sizeof(*searchKey));
456 searchKey->equivalent = (KEYED_INDEX **)malloc(
sizeof(*(searchKey->equivalent)));
457 searchKey->equivalent[0] = &keyedIndex;
458 searchKey->equivalents = 1;
461 keyedIndex.stringKey = *(
char **)searchKeyData;
464 keyedIndex.doubleKey = *(
double *)searchKeyData;
467 if (i < 0 || keyGroup[i]->nextIndex >= keyGroup[i]->equivalents)
469 rowIndex = keyGroup[i]->equivalent[keyGroup[i]->nextIndex]->rowIndex;
471 keyGroup[i]->nextIndex += 1;
488 long i, keyGroups, i1, j, istart, jstart, i2, j2;
489 KEYED_EQUIVALENT **keyGroup;
490 char **tmpstring = NULL;
491 double *tmpdata = NULL;
495 index = (
long *)malloc(
sizeof(*index) * rows);
498 tmpstring = (
char **)data;
503 tmpdata = (
double *)data;
505 tmpdata = calloc(
sizeof(*tmpdata), rows);
506 for (i = 0; i < rows; i++) {
509 tmpdata[i] = *((
short *)data + i);
512 tmpdata[i] = *((
unsigned short *)data + i);
515 tmpdata[i] = *((int32_t *)data + i);
518 tmpdata[i] = *((uint32_t *)data + i);
521 tmpdata[i] = *((
unsigned char *)data + i);
524 tmpdata[i] = *((
float *)data + i);
527 fprintf(stderr,
"Invalid data type given!\n");
542 istart = keyGroups - 1;
544 for (i = istart, i2 = 0; i2 < keyGroups; i2++) {
548 jstart = keyGroup[i]->equivalents - 1;
550 for (j = jstart, j2 = 0; j2 < keyGroup[i]->equivalents; j2++) {
553 ((
char **)data)[i1] = keyGroup[i]->equivalent[j]->stringKey;
556 ((
double *)data)[i1] = keyGroup[i]->equivalent[j]->doubleKey;
559 ((
float *)data)[i1] = (float)keyGroup[i]->equivalent[j]->doubleKey;
562 ((int32_t *)data)[i1] = (int32_t)keyGroup[i]->equivalent[j]->doubleKey;
565 ((uint32_t *)data)[i1] = (uint32_t)keyGroup[i]->equivalent[j]->doubleKey;
568 ((
short *)data)[i1] = (short)keyGroup[i]->equivalent[j]->doubleKey;
571 ((
unsigned short *)data)[i1] = (
unsigned short)keyGroup[i]->equivalent[j]->doubleKey;
574 ((
char *)data)[i1] = (
unsigned char)keyGroup[i]->equivalent[j]->doubleKey;
577 fprintf(stderr,
"Invalid data type given!\n");
581 index[i1] = keyGroup[i]->equivalent[j]->rowIndex;
593 for (i = 0; i < keyGroups; i++) {
594 free(keyGroup[i]->equivalent);
611int strcmp_skip(
const char *s1,
const char *s2,
const char *skip) {
614 while (*s1 && strchr(skip, *s1))
616 while (*s2 && strchr(skip, *s2))
623 }
while (*s1 && *s2);
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
#define SDDS_ULONG
Identifier for the unsigned 32-bit integer data type.
#define SDDS_FLOAT
Identifier for the float data type.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
#define SDDS_SHORT
Identifier for the signed short integer data type.
#define SDDS_CHARACTER
Identifier for the character data type.
#define SDDS_USHORT
Identifier for the unsigned short integer data type.
#define SDDS_DOUBLE
Identifier for the double data type.
long binaryIndexSearch(void **array, long members, void *key, int(*compare)(const void *c1, const void *c2), long bracket)
Searches for a key in a sorted array of pointers using binary search.
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
int unique(void *base, size_t n_items, size_t size, int(*compare)(const void *a, const void *b), void(*copy)(void *a, void *b))
Remove duplicate elements from a sorted array.
int CompareDoubleKeyedIndex(const void *ki1, const void *ki2)
Compare two KEYED_INDEX structures based on double keys.
void set_up_row_sort(int sort_by_column, size_t n_columns, size_t element_size, int(*compare)(const void *a, const void *b))
Set up parameters for row-based sorting.
int double_abs_cmpasc(const void *a, const void *b)
Compare the absolute values of two doubles in ascending order.
KEYED_EQUIVALENT ** MakeSortedKeyGroups(long *keyGroups, long keyType, void *data, long points)
Create sorted key groups from data.
int double_cmpdes(const void *a, const void *b)
Compare two doubles in descending order.
int CompareStringKeyedIndex(const void *ki1, const void *ki2)
Compare two KEYED_INDEX structures based on string keys.
int long_cmpasc(const void *a, const void *b)
Compare two long integers in ascending order.
int double_cmpasc(const void *a, const void *b)
Compare two doubles in ascending order.
int CompareDoubleKeyedGroup(const void *kg1, const void *kg2)
Compare two KEYED_EQUIVALENT groups based on double keys.
long * sort_and_return_index(void *data, long type, long rows, long increaseOrder)
Sort data and return the sorted index.
int long_abs_cmpasc(const void *a, const void *b)
Compare the absolute values of two long integers in ascending order.
int CompareStringKeyedGroup(const void *kg1, const void *kg2)
Compare two KEYED_EQUIVALENT groups based on string keys.
int string_cmpasc(const void *a, const void *b)
Compare two strings in ascending order.
int row_compare(const void *av, const void *bv)
Compare two rows based on the previously set sorting parameters.
long FindMatchingKeyGroup(KEYED_EQUIVALENT **keyGroup, long keyGroups, long keyType, void *searchKeyData, long reuse)
Find a matching key group for a search key.
int double_abs_cmpdes(const void *a, const void *b)
Compare the absolute values of two doubles in descending order.
void string_copy(void *a, void *b)
Copy a string value.
int strcmp_skip(const char *s1, const char *s2, const char *skip)
Compare two strings while skipping specified characters.
char * strcpy_ss(char *dest, const char *src)
Safely copies a string, handling memory overlap.