forked from okbob/pspg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sort.c
134 lines (120 loc) · 2.27 KB
/
sort.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*-------------------------------------------------------------------------
*
* sort.c
* sort of data inside columns
*
* Portions Copyright (c) 2017-2023 Pavel Stehule
*
* IDENTIFICATION
* src/sort.c
*
*-------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <string.h>
#include "pspg.h"
static inline int
signof(double n)
{
if (n < 0)
return -1;
else if (n > 0)
return 1;
else
return 0;
}
static int
compar_num_asc(const void *a, const void *b)
{
SortData *sda = (SortData *) a;
SortData *sdb = (SortData *) b;
if (sdb->info == INFO_DOUBLE)
{
if (sda->info == INFO_DOUBLE)
/*
* Without using signof function there is possible problem with
* mapping of 8bytes double to 4bytes int (the sign of result value
* after casting can be wrong).
*/
return signof(sda->d - sdb->d);
else
return 1;
}
else
{
if (sda->info == INFO_DOUBLE)
return -1;
else
return 0;
}
}
static int
compar_num_desc(const void *a, const void *b)
{
SortData *sda = (SortData *) a;
SortData *sdb = (SortData *) b;
if (sdb->info == INFO_DOUBLE)
{
if (sda->info == INFO_DOUBLE)
return signof(sdb->d - sda->d);
else
return 1;
}
else
{
if (sda->info == INFO_DOUBLE)
return -1;
else
return 0;
}
}
void
sort_column_num(SortData *sortbuf, int rows, bool desc)
{
qsort(sortbuf, rows, sizeof(SortData), desc ? compar_num_desc : compar_num_asc);
}
static int
compar_text_asc(const void *a, const void *b)
{
SortData *sda = (SortData *) a;
SortData *sdb = (SortData *) b;
if (sdb->info == INFO_STRXFRM)
{
if (sda->info == INFO_STRXFRM)
return strcmp(sda->strxfrm, sdb->strxfrm);
else
return 1;
}
else
{
if (sda->info == INFO_STRXFRM)
return -1;
else
return 0;
}
}
static int
compar_text_desc(const void *a, const void *b)
{
SortData *sda = (SortData *) a;
SortData *sdb = (SortData *) b;
if (sdb->info == INFO_STRXFRM)
{
if (sda->info == INFO_STRXFRM)
return strcmp(sdb->strxfrm, sda->strxfrm);
else
return 1;
}
else
{
if (sda->info == INFO_STRXFRM)
return -1;
else
return 0;
}
}
void
sort_column_text(SortData *sortbuf, int rows, bool desc)
{
qsort(sortbuf, rows, sizeof(SortData), desc ? compar_text_desc : compar_text_asc);
}