-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnsort.cpp
308 lines (278 loc) · 9.28 KB
/
nsort.cpp
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
//*****************************************************************
//
// NSORT.CPP - NDIR data-sorting routines
//
// Written by: Daniel D. Miller (the Derelict)
//
//*****************************************************************
// #undef __STRICT_ANSI__
#include <windows.h>
// #include <string.h>
#ifdef _lint
#include <malloc.h>
#endif
#include "common.h"
#include "ndir32.h"
//lint -e1013 Symbol 'LowPart' not a member of class '_LARGE_INTEGER'
//lint -e40 Undeclared identifier 'LowPart'
//lint -e63 Expected an lvalue
//*************** function prototypes ***************
static int sort_lfn_name(struct ffdata *a, struct ffdata *b);
static int sort_ext(struct ffdata *a, struct ffdata *b);
static int sort_size(struct ffdata *a, struct ffdata *b);
// static int sort_date(struct ffdata *a, struct ffdata *b);
// static int sort_time(struct ffdata *a, struct ffdata *b);
static int sort_lfn_name_rev(struct ffdata *a, struct ffdata *b);
static int sort_ext_rev(struct ffdata *a, struct ffdata *b);
static int sort_size_rev(struct ffdata *a, struct ffdata *b);
// static int sort_date_rev(struct ffdata *a, struct ffdata *b);
// static int sort_time_rev(struct ffdata *a, struct ffdata *b);
static struct ffdata *merge_sort(struct ffdata *c);
static struct ffdata *merge(struct ffdata *a, struct ffdata *b);
//************************************************************
// the following object is a dummy point structure
// which is used by merge_sort. The main code must
// allocate a strucure for this to point to.
//
// A global function pointer is also required by the
// sort routine. This will point to a function which
// accepts two structure pointers as arguments, and
// returns:
//
// >0 if a > b
// ==0 if a == b
// <0 if a < b
//
//************************************************************
static struct ffdata *z = NULL ;
static int (*sort_fcn) (struct ffdata *a, struct ffdata *b) ;
//****************************************************
// allocate a dummy structure for merge_sort()
//****************************************************
static int init_sort(void)
{
// z = new ffdata ;
z = (struct ffdata *) malloc(sizeof(ffdata)) ;
if (z == NULL)
error_exit(OUT_OF_MEMORY, NULL) ;
z->next = NULL ;
return DATA_OKAY ;
}
//****************************************************
// void free_file_structs(void)
// {
// if (z != NULL) delete z ;
// }
//*********************************************************
static int sort_lfn_name(struct ffdata *a, struct ffdata *b)
{
return(_tcsicmp(a->filename, b->filename)) ;
}
//*********************************************************
static int sort_ext(struct ffdata *a, struct ffdata *b)
{
return(_tcsicmp(a->ext, b->ext)) ;
}
//*********************************************************
static int sort_size(struct ffdata *a, struct ffdata *b)
{
if (a->fsize > b->fsize) return(1) ;
else if (b->fsize > a->fsize) return(-1) ;
else return(0) ;
}
//*********************************************************
// static int sort_date(struct ffdata *a, struct ffdata *b)
// {
// if (a->ft > b->ft) return(1) ;
// else if (b->ft > a->ft) return(-1) ;
// else
// return(0) ;
// }
//*********************************************************
static int sort_date_time(struct ffdata *a, struct ffdata *b)
{
LARGE_INTEGER a64, b64 ;
a64.LowPart = a->ft.dwLowDateTime ;
a64.HighPart = a->ft.dwHighDateTime ;
b64.LowPart = b->ft.dwLowDateTime ;
b64.HighPart = b->ft.dwHighDateTime ;
if (a64.QuadPart > b64.QuadPart) return(1) ; //lint !e530
else if (a64.QuadPart < b64.QuadPart) return(-1) ; //lint !e530
else
return(0) ;
} //lint !e550
//*********************************************************
static int sort_lfn_name_rev(struct ffdata *a, struct ffdata *b)
{
return(_tcsicmp(b->filename, a->filename)) ;
}
//*********************************************************
static int sort_ext_rev(struct ffdata *a, struct ffdata *b)
{
return(_tcsicmp(b->ext, a->ext)) ;
}
//*********************************************************
static int sort_size_rev(struct ffdata *a, struct ffdata *b)
{
if (b->fsize > a->fsize) return(1) ;
else if (a->fsize > b->fsize) return(-1) ;
else return(0) ;
}
//*********************************************************
// static int sort_date_rev(struct ffdata *a, struct ffdata *b)
// {
// if (b->ft > a->ft) return(1) ;
// else if (a->ft > b->ft) return(-1) ;
// else
// return(0) ;
// }
//*********************************************************
static int sort_date_time_rev(struct ffdata *a, struct ffdata *b)
{
// if (b->ft > a->ft) return(1) ;
// else if (a->ft > b->ft) return(-1) ;
// else
// return(0) ;
LARGE_INTEGER a64, b64 ;
a64.LowPart = a->ft.dwLowDateTime ;
a64.HighPart = a->ft.dwHighDateTime ;
b64.LowPart = b->ft.dwLowDateTime ;
b64.HighPart = b->ft.dwHighDateTime ;
if (a64.QuadPart < b64.QuadPart) return(1) ; //lint !e530
else if (a64.QuadPart > b64.QuadPart) return(-1) ; //lint !e530
else
return(0) ;
} //lint !e550
//*********************************************************
// this function returns
// <0 if (a) is DIR and (b) is not
// >0 if (b) is DIR and (a) is not
// ==0 if (a) and (b) are same type (DIR or not)
//*********************************************************
static int sort_dir(struct ffdata *a, struct ffdata *b)
{
if (a->dirflag && !(b->dirflag)) return(-1) ;
else if (b->dirflag && !(a->dirflag)) return(1) ;
else return(0) ;
}
//*********************************************************
// This routine recursively splits linked lists
// into two parts, passing the divided lists to
// merge() to merge the two sorted lists.
//*********************************************************
static struct ffdata *merge_sort(struct ffdata *c)
{
struct ffdata *a, *b, *prev ;
int pcount = 0 ;
int j = 0 ;
if ((c != NULL) && (c->next != NULL))
{
a = c ;
while (a != NULL)
{
pcount++ ;
a = a->next ;
}
a = c ;
b = c ;
prev = b ;
while (j < pcount/2)
{
j++ ;
prev = b ;
b = b->next ;
}
prev->next = NULL ; //lint !e771
return merge(merge_sort(a), merge_sort(b)) ;
}
return c ;
}
//*********************************************************
// This routine merges two sorted linked lists.
//*********************************************************
static struct ffdata *merge(struct ffdata *a, struct ffdata *b)
{
struct ffdata *c ;
c = z ;
do
{
int x = sort_fcn(a, b) ;
if (x <= 0)
{
c->next = a ;
c = a ;
a = a->next ;
}
else
{
c->next = b ;
c = b ;
b = b->next ; //lint !e613
}
}
while ((a != NULL) && (b != NULL));
if (a == NULL) c->next = b ; //lint !e613
else c->next = a ; //lint !e613
return z->next ;
}
//*********************************************************
// This intermediate function is used because I want
// merge_sort() to accept a passed parameter,
// but in this particular application the initial
// list is global. This function sets up the global
// comparison-function pointer and passes the global
// list pointer to merge_sort().
//*********************************************************
static void sort_files(int (*current_sort)(struct ffdata *a, struct ffdata *b))
{
sort_fcn = current_sort ;
ftop = merge_sort(ftop) ;
}
//*****************************************************************
void sort_filelist(void)
{
if (z == 0)
init_sort() ;
// reverse sort
if (n.reverse) {
switch (n.sort) {
case SORT_EXT:
sort_files(sort_lfn_name_rev) ;
sort_files(sort_ext_rev) ;
break;
case SORT_NAME:
sort_files(sort_ext_rev) ;
sort_files(sort_lfn_name_rev) ;
break;
case SORT_SIZE:
sort_files(sort_size_rev) ;
break;
case SORT_DATE:
sort_files(sort_date_time_rev) ;
break;
default: break ; // make lint happy
}
}
// normal sort
else {
switch (n.sort) {
case SORT_EXT:
sort_files(sort_lfn_name) ;
sort_files(sort_ext) ;
break;
case SORT_NAME:
sort_files(sort_ext) ;
sort_files(sort_lfn_name) ;
break;
case SORT_SIZE:
sort_files(sort_size) ;
break;
case SORT_DATE:
sort_files(sort_date_time) ;
break;
default: break ; // make lint happy
}
}
if (n.dir_first)
sort_files(sort_dir) ;
}